微服务不是银弹
微服务热
这些年,几乎所有做软件系统的团队都绕不开一个词:微服务。
只要系统稍微复杂一点,就有人建议拆成微服务;只要团队交付效率不高,就有人说应该上微服务;只要系统改不动了,就有人认为问题在于它还是单体应用。好像只要把一个应用拆成许多个服务,复杂度就会自然消失,团队协作就会自然顺畅,系统也会自然变得高可用、高并发、易扩展。
这种想法很有诱惑力。因为微服务确实解决了一些真实问题:它可以让不同模块独立部署,可以让不同团队围绕服务独立演进,可以让系统在技术栈、容量、发布节奏上获得更大的灵活性。对于业务规模足够大、组织分工足够清楚、工程能力足够成熟的公司来说,微服务是非常有效的架构方式。
但问题也恰恰在这里。微服务是一种有效的技术方案,却不是一种万能的组织解药。它可以帮助我们管理一部分技术复杂度,但不能替我们理解业务;它可以让已经清楚的服务边界变得更容易治理,却不能凭空创造出业务边界;它可以拆分系统,但不能自动拆分责任。
在很多团队里,微服务被寄予了过高的期望。我们希望它解决系统难维护的问题,解决需求变化快的问题,解决团队协作混乱的问题,甚至解决业务流程不清的问题。结果往往是,原来一个单体应用里的混乱,被拆散到了几十个服务里;原来一次本地方法调用能完成的事情,变成了多次网络调用;原来一个日志文件里能看到的问题,变成了跨服务、跨队列、跨数据库的链路追踪。
所以,在讨论微服务之前,我们需要先问一个更朴素的问题:我们到底需要什么样的服务?
从 SOA 说起
如果从企业信息化的角度看,真正重要的其实不是“微”,而是“服务”。
在微服务流行之前,企业软件领域已经长期讨论 SOA,也就是面向服务的架构。SOA 的出发点并不是把一个应用拆得更小,而是把企业内部的业务能力以服务的形式表达出来。订单、客户、库存、结算、合同、审批、支付、消息,这些能力不应该只是某个系统里的内部模块,而应该成为企业可以复用、组合和编排的业务服务。
这背后的思想是很有价值的。企业信息系统不是一个孤立的软件产品,而是业务流程的技术表达。一个订单从创建到履约,可能会经过客户管理、商品管理、价格计算、库存锁定、支付、开票、发货、售后等多个环节。每个环节都可能由不同系统承载。如果这些系统之间没有清晰的服务边界和稳定的接口,业务流程就只能靠点对点集成、数据库共享、人工导入导出或者临时脚本拼起来。
从这个角度看,SOA 比“微服务”这个词更接近企业真正关心的问题。企业关心的不是服务大小,而是业务能力能不能被清楚地定义、稳定地复用、有效地组合。一个客户服务是否能被销售、合同、售后同时使用?一个库存服务是否能同时支撑订单、调拨和采购?一个审批服务是否能被不同业务线复用?这些问题比“一个服务应该多少行代码”更重要。
但是 SOA 后来的实践并不总是成功。很多 SOA 项目变得庞大、笨重而缓慢。企业服务总线、统一数据模型、集中治理平台、复杂的服务编排,让原本想提升灵活性的架构变成了新的瓶颈。所有系统都要接入统一平台,所有接口都要遵循统一规范,所有变更都要经过集中审批。看起来架构很完整,实际业务变化却越来越慢。
这并不是说 SOA 这个概念本身必然导致笨重,而是很多企业级 SOA 实践走向了重治理、重平台、重标准化。SOA 的问题不在于“服务化”这个方向错了,而在于它常常过于中心化、过于宏大,也过于相信自上而下的设计。企业业务本身是不断变化的,不同业务线的节奏并不一致。试图提前设计出一个覆盖全企业的统一服务体系,往往会低估业务的复杂性和变化速度。
微服务的出现,有它的必然性。它反对过度中心化,强调小团队自治,强调服务可以独立开发、独立测试、独立部署,强调每个服务围绕清晰的业务能力演进。相比传统 SOA,微服务更加轻量,也更加适合互联网时代快速变化的业务环境。
但是,微服务并没有否定 SOA 中最重要的那件事:核心业务服务应该围绕业务能力来定义。只是它把服务治理从庞大的中心平台,更多地转移到了团队、工程实践和自动化基础设施上。
服务不清楚,微服务就没有意义
微服务的核心不是把系统拆小,而是把系统拆对。
如果一个企业没有清晰的业务架构,不知道自己的核心业务能力是什么,不知道不同业务流程之间如何协作,不知道哪些概念应该统一、哪些概念应该隔离,那么微服务解决不了这个问题。
服务边界来自业务边界,而不是来自技术分层。用户服务、订单服务、库存服务这些名字看起来很自然,但真正落到业务系统里,边界往往没有那么简单。订单在交易上下文里是一份购买意向和履约承诺,在财务上下文里可能是收入确认的依据,在售后上下文里又是退款和退货的入口。它们都叫订单,却未必应该共用同一个模型。
如果没有把这些业务含义讲清楚,拆服务就会变成按表拆、按页面拆、按技术层拆。一个系统里有用户表,就拆一个用户服务;有订单表,就拆一个订单服务;有商品表,就拆一个商品服务。这样拆出来的服务看起来符合微服务风格,实际只是把数据库表外面包了一层接口。业务规则仍然散落在各个调用方,服务本身没有承载真正的业务能力。
微服务不能替代业务建模。一个团队如果在单体应用里无法说清楚模块边界,换成微服务以后也很难说清楚服务边界。相反,微服务会放大这种不清楚。因为服务之间一旦通过网络接口连接,边界的调整成本会更高;接口一旦被多个服务依赖,修改就不再是一次内部重构,而变成了跨团队协作。
所以,微服务之前应该先有服务。服务之前应该先有业务能力的识别。一个核心业务服务应该回答几个基本问题:它代表什么业务能力?它服务于哪个业务流程?它拥有哪些数据?它对外承诺什么接口?它的变化由谁负责?它和其它服务之间是协作、依赖,还是上下游关系?
当然,并不是每个服务都必须直接对应一个业务流程。认证、通知、文件、网关、配置、任务调度、监控等支撑性服务,也可能在微服务体系中独立存在。但即使是这类服务,也应该有清晰而稳定的职责边界。真正危险的不是存在技术支撑服务,而是把技术分层、数据库表或者页面功能包装成服务,然后误以为这就是业务能力拆分。
如果这些问题答不上来,那么先不要急着谈微服务。
微服务的成本
微服务不是免费午餐。它把一部分复杂度从代码内部转移到了系统之间。
在单体应用中,模块之间的调用通常是进程内调用。调用失败的可能性相对简单,事务边界也比较容易处理。拆成微服务以后,调用变成了网络调用。网络是不可靠的,服务可能不可用,响应可能超时,请求可能重复,消息可能乱序,部分成功和部分失败会成为常态。
这意味着我们需要处理一系列过去不那么明显的问题:服务注册与发现、负载均衡、限流、熔断、超时、重试、幂等、分布式事务、消息一致性、链路追踪、集中日志、指标监控、配置管理、灰度发布、版本兼容、接口治理、权限控制、故障演练。每一个问题都有成熟方案,但每一个方案都需要成本。
这些成本不仅是技术成本,也是组织成本。微服务要求团队具备更强的工程能力。自动化测试要跟得上,持续集成和持续部署要稳定,环境管理要清楚,监控告警要有效,故障定位要有工具支持。否则,服务越拆越多,发布越发频繁,问题也会越发难以定位。
很多团队低估了这种成本。他们看到的是微服务带来的独立部署和灵活扩展,却忽略了支撑这些能力的基础设施。没有稳定的 CI/CD,没有完善的观测体系,没有清晰的接口管理,没有成熟的故障处理机制,微服务只会让系统变得更加脆弱。
还有一个常见误解,是把前后端分离和微服务混为一谈。
前后端分离解决的是用户界面和后端接口之间的协作问题。它让前端可以独立开发和发布,让后端通过 API 提供数据和能力。这是一种非常重要的工程实践,但它不等于微服务。一个单体后端同样可以很好地支持前后端分离;一个微服务后端也可能对前端暴露出混乱的接口。
如果只是把原来一个 Web 应用改成前端调用后端 API,这不是微服务。如果只是把后端按页面拆成多个接口项目,也不是微服务。微服务关注的是业务能力的自治、服务边界的清晰以及独立演进的能力,而不是前端代码和后端代码是否放在同一个项目里。
因此,不能因为做了前后端分离,就认为系统已经服务化;也不能因为想做前后端分离,就顺手把后端拆成一堆微服务。
什么时候需要拆
既然微服务有这么多成本,是不是就不应该使用微服务?当然不是。
微服务解决的是特定阶段、特定规模下的真实问题。当一个系统的业务能力已经比较清楚,不同模块的变化节奏明显不同,不同团队需要并行开发和独立发布,某些能力需要单独扩容或高可用,单体应用已经成为组织协作和系统演进的瓶颈时,微服务就是值得考虑的方案。
反对盲目微服务,并不等于否定微服务。好的微服务架构可以让系统边界更显式,让团队责任更清楚,让高变化、高负载、高复用的能力独立演进。问题不在于微服务本身,而在于很多团队在业务边界、工程能力和组织责任都没有准备好的情况下,把微服务当成了架构捷径。
比如,一个电商系统中,商品搜索、库存、订单、支付、营销、推荐、售后等能力,可能由不同团队负责,使用不同的数据模型,有不同的性能要求和发布节奏。搜索服务可能需要独立的索引和高读性能,库存服务需要严格控制扣减规则,营销服务变化频繁,支付服务要求更高的稳定性和安全性。这个时候,让所有能力都挤在一个应用里,反而会让系统越来越难维护。
再比如,某个业务能力不仅被一个系统使用,而是被多个业务线共同依赖。它有稳定的业务职责,有明确的数据所有权,也有独立演进的需求。把它作为服务沉淀出来,就不是为了追求架构形式,而是为了复用和治理企业能力。
但是,在业务量还不大、团队规模还不大、业务模型还没有稳定之前,不要急着拆出一堆服务。业务量当然不是唯一标准,有些能力即使调用量不大,也可能因为合规、安全、复用、团队边界或者发布节奏不同而值得独立出来。但如果没有独立演进、独立扩容、独立治理或复用需求,仅仅为了架构先进而拆,收益通常不够。早期系统最重要的是快速验证业务,保持简单和可修改。这个阶段过早微服务化,很容易把精力消耗在基础设施、部署、接口联调和分布式问题上,反而降低了业务试错速度。
很多系统真正需要的不是微服务,而是一个边界清楚的单体应用。模块化单体并不落后。只要内部模块边界清楚,依赖关系受控,数据库访问不混乱,测试覆盖足够,发布流程稳定,一个单体应用可以支撑相当长时间的业务发展。
好的拆分通常是演进出来的,而不是一开始画出来的。随着业务发展,我们逐渐发现哪些模块变化最频繁,哪些能力被多个地方复用,哪些部分有独立扩容需求,哪些团队之间互相阻塞。这个时候,再把边界清楚、职责稳定、收益明确的部分拆出来,成功概率会高得多。
微服务应该是对复杂度的回应,而不是制造复杂度的起点。
有选择地应用
架构选择最怕两种极端。一种是看到复杂度就拆,另一种是看到成本就拒绝拆。
微服务既不是银弹,也不是洪水猛兽。它是一种架构工具。工具的价值取决于场景,也取决于使用者的能力。对一个成熟团队来说,微服务可以带来灵活性、自治性和扩展性;对一个还没有建立基本工程纪律的团队来说,微服务会把所有问题放大。
是否采用微服务,可以从几个问题开始判断。
第一,业务边界是否清楚?如果边界不清楚,先做业务梳理和领域建模,而不是先拆服务。
第二,团队边界是否清楚?如果所有代码仍然由同一小组维护,所有需求都按同一个节奏发布,拆成多个服务未必有收益。
第三,是否存在独立部署的真实需求?如果每次发布仍然需要所有服务一起上线,那么所谓微服务只是分布式单体。
第四,是否具备必要的工程基础设施?没有自动化测试、持续交付、监控告警和链路追踪,微服务的维护成本会非常高。
第五,拆分收益是否大于协作成本?如果一个服务拆出去以后,大量需求仍然需要跨服务联调、跨团队协调、跨数据库一致性处理,那么这个边界可能并不合适。
这些问题没有标准答案,但它们能帮助我们回到架构设计的本质:架构不是为了先进,而是为了让系统在当前和未来一段时间内更容易变化。
真正成熟的技术团队,不会因为行业都在谈微服务就盲目跟进,也不会因为微服务有成本就完全拒绝。它会根据业务阶段、团队能力和系统复杂度做选择。该单体的时候单体,该模块化的时候模块化,该服务化的时候服务化,该微服务的时候再微服务。
结语
微服务的价值,建立在清晰的服务之上;服务的价值,建立在清晰的业务能力之上。
如果业务架构缺失,微服务解决不了问题。它只能把问题拆散,让问题以更多接口、更多调用链、更多部署单元的形式出现。如果团队工程能力不足,微服务也解决不了问题。它只会把原来可以在一个进程里处理的复杂度,变成跨网络、跨服务、跨团队的复杂度。
从企业角度看,我们真正需要的是能够支撑业务流程、沉淀业务能力、适应业务变化的服务体系。SOA 提醒我们,服务应该和企业能力相关;微服务提醒我们,服务不应该被庞大的中心化治理拖死。两者并不是简单的新旧替代关系,而是在不同阶段、不同组织能力下对服务化思想的不同实践。
所以,比“要不要上微服务”更重要的问题是:我们的业务能力是否清楚?服务边界是否自然?团队是否有能力独立交付?系统是否真的需要独立扩展?我们是否愿意承担分布式系统的成本?
如果这些问题还没有答案,先不要急着拆服务。先把业务讲清楚,把模块边界理清楚,把工程纪律建立起来。等到系统真的长到需要拆的时候,微服务会是一种自然的选择,而不是一种赶时髦的姿态。
微服务不是解决一切问题的银弹。它只是复杂系统发展到一定阶段后,帮助我们管理复杂度的一种方法。用得合适,它能让系统更灵活;用得过早,它只会让复杂度提前到来。