微服务 vs 模块化单体:20 人以下团队的决策框架
一个由十二名工程师组成的团队每三周交付一次新功能。他们的构建流水线运行着十七个服务,部署需要协调四个仓库,而上周二一个损坏的用户偏好设置端点使结账流程宕机了九十分钟。从纸面上看,他们的架构没有任何问题。它只是不适合他们。在微服务与模块化单体之间做选择,很少是一个纯粹的技术问题。它是一个关于你的架构的运维成本是否与必须运维它的团队规模和速度相匹配的问题。
隐藏的成本不是代码,而是运维
对于二十人以下的团队而言,为通过 HTTP 暴露某项能力所编写的代码,相比于你必须围绕它构建的一切,都是微不足道的。每个服务都需要自己的部署流水线、自己的监控、自己的告警规则、自己的 on-call 手册、自己的数据库迁移方案,以及与调用它的服务之间自己的契约测试。无论该服务做一件事还是一百件事,这套基础设施的成本大致相同。当一个小团队运行十二个服务时,他们要用同一批本应在做产品的工程师,把那份固定成本付上十二遍。
模块化单体则颠覆了这个比例。一条部署流水线。一个日志流。一个具有共享迁移时间线的数据库。模块之间通过类型化的函数调用进行通信,这些调用在编译时失败,而不是像 JSON 契约那样在凌晨三点的生产环境中失败。保持模块边界清晰的纪律仍然是实实在在的工作,但运维开销接近于零。结果是,一个十人团队几乎无需专门的平台投入,就能运维一个结构良好的单体;而同样规模的团队若运行微服务,通常会有一到两名工程师被基础设施工作永久性地占用。
正面对决:两者显著分化的五个决策点
部署节奏
从理论上讲,微服务允许独立部署。但在实践中,小团队很少拥有真正独立的服务。对定价服务的一次变更,通常需要与订单服务和开票服务进行协调发布。你继承了单体的协调成本,却失去了单体一次性原子部署的安全性。模块化单体只需部署一次。整个系统要么工作,要么一起回滚。对于按周而非按小时交付的团队,这在速度和可预测性上都占优。
调试
当微服务系统中的一个请求失败时,你要跟随它跨越三到四跳的网络、反序列化、重试和超时。分布式追踪有所帮助,但无法替代堆栈跟踪。在模块化单体中,一次堆栈跟踪就能在一个屏幕上显示整个调用路径。对于小团队而言,工程师花在调试上的工时是公司最稀缺的资源。任何能减少调试时间的做法,都直接转化为功能交付速度,而这又直接转化为收入。
扩展
支持微服务的经典论点是可以独立扩展热点组件。这确实成立,但在二十人团队所处的规模上很少真正相关。大多数系统在遇到任何单一服务的 CPU 瓶颈之前,早就在数据库上撞墙了。一个设计良好的单体,配上只读副本、缓存层和后台任务队列,能处理的流量远超人们的预期。如果你确实撑不住了,模块化的边界会让把某个热点模块抽取为独立服务变成一次直接的重构,而不是从零开始的重写。
招聘与入职
微服务团队的新工程师,前两周要花在学习部署工具、服务目录、共享库,以及状态所在的十二个位置上。而在模块化单体上,他们只需克隆一个仓库,运行一条命令,第二天就能在 IDE 里端到端地追踪任何行为。在一个高级工程师昂贵、产出时间以周计量的招聘市场里,单体大幅降低了入职成本。这是你没有花出去的钱,也是你更早获得的产能。
故障隔离
这是微服务真正胜出的一点。一个服务中的 bug 不会直接让其他服务崩溃。但对于小团队来说,“不崩溃”往往意味着“悄无声息地返回过期或错误的数据”,这可以说比一次明确的宕机更糟,因为检测起来更花时间。断路器、超时、带退避的重试以及优雅降级都不易做好,而小团队几乎总是在这方面投入不足。单体则会响亮而彻底地失败,这更容易告警,也更容易恢复。
微服务真正划算的时候
有三种模式,能让微服务诚实地赚回它的运维税。第一,当系统的不同部分具有真正不同的运行时特征时:一条实时视频处理流水线,紧挨着一个只服务十名内部用户的 CRUD 管理面板。第二,当独立团队需要以独立节奏交付而无需协调开销时,这通常意味着你已经跨过了 30 到 40 名工程师的门槛,组织边界已经硬化。第三,当某个单一组件具有硬性的扩展要求,例如一个每小时接收数百万请求的事件摄入端点,若与其他部分同处一处,会扭曲一切的资源形态。
如果这三种情况都不适用于你的业务,那么微服务几乎可以肯定成本高于收益。而值得你对自己诚实的是:它们究竟是今天真的适用,还是可能只是在某个也许永远不会到来的假想未来才适用。
模块化单体作为桥梁
对于二十人以下的团队,最站得住脚的架构是一个模块化单体,模块之间具有清晰、被强制执行的边界。每个模块拥有自己的数据。它向其他模块暴露一个狭窄的、类型化的接口。没有跨模块的直接数据库读取,没有循环依赖,也没有跨越边界泄漏的共享可变状态。用目录结构、包规则、lint 和代码审查来强制执行这些约束。把每一次违规都当作真正的 bug 来对待。
做得好,这就同时给了你今天所需要的运维简洁性,以及你两年后可能需要的架构选项。当某一天某个模块真的需要独立扩展或按自己的节奏交付时,抽取它就成为一次机械式的重构,而不是一个跨越多个季度的考古项目。你只在真正需要时才获得微服务的收益,也只在那时才为它们付费。
正确的架构,是你的团队在当前规模下能够良好运维、并且对你未来可能达到的规模有清晰演进路径的那一个。对大多数中小企业规模的团队来说,那是一个模块化单体,而不是一个分布式系统。如果你正在权衡一次重新设计,或者你继承了一堆正在拖慢团队的微服务蔓延,一位有经验的合作伙伴可以帮你梳理真实的成本面,并设计一条不会让你路线图停摆的迁移路径。MerkTechs 团队在电商、金融科技和内部工具等客户项目中都走过这条路,我们很乐意就你的具体情况聊一聊各种权衡。