"微服务"这三个字,我听了快十年了。从一开始觉得它很革命,到后来觉得它很套路,再到现在——我反而想停下来问一句:这个词本身,还成立吗?

不是质疑它解决过的问题。微服务确实解决了一些真实存在的痛点。我质疑的是——这十年里,我们用同一个词,描述了太多不同的事,最后把"什么是好的微服务"这个问题,搞得比"什么是好的代码"还要难回答。

微服务解决的是「拆」的问题

2014 年我第一次认真读 Martin Fowler 那篇关于微服务的文章,最打动我的不是"小",是"自治"。一个服务拥有自己的数据、自己的发布节奏、自己的失败模式。它和"库"是两种根本不同的组织方式——库是被嵌入的,服务是被调用的。

这种"边界感"是真正有价值的东西。它强迫团队在动手之前,先想清楚"这个能力归谁"。在单体时代这个问题是糊在一起的——所有逻辑都在一个进程里,谁调用谁全靠口头约定。微服务把这层口头约定,变成了网络调用、契约、版本号。

十年前我刚做第一个微服务项目的时候,觉得"拆"本身是好玩的。拆得越细越觉得优雅。直到后来我拆了三个项目,才慢慢意识到——拆,从来不是问题;拆错,才是问题。

我见过的三种"拆错"

第一种:按技术层拆。 经典反模式。用户服务、订单服务、商品服务、库存服务,每个服务里再来 controller / service / dao 三层。和单体时代唯一区别是——以前一个进程内的方法调用,现在变成 HTTP 调用,慢了十倍,调试难了一百倍。这种拆法,本质是把单体的复杂度平移到了网络上,没有创造任何新价值。

第二种:按团队拆。 "我们组三个人,那就拆三个服务。" 拆完之后每个服务都很小,但每个服务都是个全栈——要管数据库、缓存、消息、监控、发布。一个人维护三个小服务,比一个人维护一个稍大的服务更累。微服务的复杂度是常数级别的,不会因为服务小就少。

第三种:按"将来可能要变"拆。 这个最常见,也最隐晦。大家都说"YAGNI",但真做架构的时候,每个人都觉得"这块以后肯定要独立"。最后系统被切得七零八落,独立出来的服务之间又通过共享数据库耦合——比单体还糟,因为它有分布式的所有成本,却没有分布式的任何收益。

三种拆错背后是同一个认知误区:把"拆"当作目标,而不是手段。

真正的转折点:业务能力切分

我真正开窍是 2021 年做供应链项目的时候。那时候我们有 17 个服务,互相调用画出来像一团毛线球。一次发布要同步 8 个仓库、上线 12 次,任何一个忘了都会出事故。团队怨声载道。

最后我们做了一次"逆向"的事——合并。把 17 个合并成 6 个。合并的原则是:「能在一个事务里完成的事,就放在一个服务里」。一句话听起来简单,但它逼着我们回答一个真问题:这个业务能力的边界到底在哪里?

合并之后我们做了一次 DDD 风格的工作坊,重新识别"限界上下文"。结果发现:原来 17 个服务里,至少 9 个的边界是错的。它们的划分不是基于业务能力,是基于"这个模块由谁开发"。

这次合并让我们明白了一件事:服务的边界应该跟着业务走,不跟着组织走。业务能力是相对稳定的——订单的"创建-确认-支付"流程三年不会大变。组织是流动的——今年这个组三个人,明年可能重组。当服务的边界跟着组织走,架构就成了组织的镜子,组织一动架构就崩。

那微服务这个词还成立吗?

成立,但需要加两个限定。

第一,它解决的是组织规模问题。当你的团队超过 50 人、单体代码超过 50 万行、跨团队的修改开始互相阻塞——微服务才有意义。一个 5 人团队维护一个 5 万行单体的项目,强行微服务化只会把简单问题复杂化。

第二,它需要的投入比想象的大得多。服务治理、链路追踪、统一配置、灰度发布、容灾降级——任何一项缺位,微服务都会变成事故制造机。如果你没准备好投入这些基础设施,单体加模块化,是更理性的选择。

现在如果有人问我"该不该上微服务",我的回答永远是同一个:先回答"你的业务能力边界画清楚了吗"。如果没画清楚,什么服务都救不了你——单体救不了,微服务也救不了。

还没想明白的事

有一个问题我到现在都没想通:业务能力的边界,到底是发现的,还是发明的?

DDD 的拥趸说"它是发现的"——业务能力客观存在,架构师只是把它识别出来。务实的工程师说"它是发明的"——任何划分都是人为选择,没有绝对的"对"。这两种说法在我脑子里打架,每次做架构设计我都会重新问自己一遍:这一刀切下去,是因为我看见了什么,还是因为我必须切?

也许答案没那么重要。也许重要的是:切的这一刀,过半年回看,它能撑住吗?