“我们有八个开发,是不是该上微服务?”这个问题还缺少几个条件:团队维护多少条业务线,谁负责部署与故障处理,系统的发布节奏是否冲突,以及业务边界是否已经稳定。人数可以说明资源约束,却不能替代这些判断。
一、先区分代码边界和部署边界
单体通常作为一个整体部署。模块化单体仍然可以整体部署,但在应用内部明确业务模块、公共接口与依赖约束。微服务进一步把部分能力放到独立部署的服务中,需要处理网络调用和独立运行带来的问题。
单一部署单元也可以具有清晰的内部结构。微软的常见 Web 应用架构指南展示了单体应用的分层与依赖组织方式。部署在一起,不意味着所有代码必须相互访问。
二、用同一组问题比较三种选择
| 选择 | 适合优先考虑的情形 | 需要持续约束的地方 |
|---|---|---|
| 单体 | 业务尚在探索,团队共同交付,独立发布需求不明显 | 避免业务规则散落,保留测试与清晰的依赖方向 |
| 模块化单体 | 业务模块逐渐清晰,但仍适合统一发布和运维 | 约束跨模块调用与数据访问,防止接口形同虚设 |
| 微服务 | 部分业务有明确的独立迭代、部署或扩展需求 | 服务契约、数据一致性、可观测性和长期运行责任 |
三、不要只计算开发一个服务的时间
可以让团队尝试回答:如果下周新增三个服务,谁负责建立环境、管理配置、更新依赖、检查告警和处理夜间故障?如果这些工作最终仍集中到一个人,拆分可能并没有消除瓶颈,只是改变了瓶颈的位置。
建议在架构评审中列出一份运行责任表。每个候选服务都应有主要负责人、备份负责人、发布方式、故障排查入口和回滚步骤。若暂时无法填完整,应先补齐工程基础,或者缩小拆分范围。
四、一个可以讨论的选择顺序
- 明确当前主要损失。是需求冲突、性能瓶颈,还是发布流程不稳定?不要用一个架构名词代替问题。
- 先设计业务边界。列出模块职责、允许的调用方向、数据管理责任和禁止的依赖。
- 评估统一部署是否仍可接受。如果可以,优先验证模块化与自动化交付能否满足当前需求。
- 只拆有明确收益的边界。当某个模块确实需要独立交付时,再评估服务化,而不是一次性拆开整个系统。
五、为未来保留选择,也为今天控制成本
模块化单体可以作为一种长期架构,也可以作为演进阶段。不要承诺“以后随时能拆”,而应通过接口、数据边界和测试持续降低未来调整的难度。反过来,已经是微服务的系统也需要定期检查:哪些服务真正独立,哪些只是把一次内部调用变成了网络调用。
在下一次架构讨论中,可以要求团队给出两份方案:维持统一部署需要做什么,拆出一个试点需要增加什么。把工作量和运行责任摆出来,再作选择,往往比争论哪种架构更先进更有效。