构建与扩展后端项目:微服务还是单体架构?

构建与扩展后端项目:微服务还是单体架构?

后端的架构,往往决定你一天的工作会有多辛苦。随着应用程序成长,最初选择留下的裂痕会慢慢浮现。总有一天你得做出决定。要守住可靠的单体架构,还是把一切都拆成微服务?

没有银弹。两种做法都有它们的位置。正确的选择,往往更取决于你的团队结构和事业阶段,而不是纯粹的技术优劣。这篇文章会谈两个主要选项,再加上一个实际上很常管用的务实中间路线。

1. 两位选手

微服务架构

微服务的想法很简单。与其建一个巨大的应用程序,不如建一群小而独立的服务。每个服务把一件事做好。

把它想成一个去中心化的团队。每个服务各自管理自己的数据库,准备好了就能部署,不用问别人准不准。账务团队想用 Go,认证团队喜欢 Rust,两边都不用让步。这种自由让团队跑得快。至少理论上是这样。

在实务上,这很适合大型组织,那种要协调 500 个开发者一起发布一次的场面,对他们来说是噩梦。

图:微服务架构

Microservices Architecture Diagram

单体架构

单体架构是传统做法。一个代码库、一个应用程序、一次部署。从用户界面到业务逻辑再到数据访问,全部住在一起。

「单体」这个词在某些圈子里已经快要变成脏话了。但它仍然有实实在在的优点。它简单。你不需要地图就能找到函数定义在哪里。部署就是一支 script。对小型和中型团队来说,这种简单就是超能力。它能让你在不被基础设施的复杂度拖累的情况下快速前进。

图:单体架构

Monolithic Architecture Diagram

2. 取舍

为什么选微服务?

微服务的代价

为什么留在单体架构?

单体架构的极限

「服务太多」的陷阱

中小型公司常见的反模式,就是最后微服务比工程师还多。我看过 100 个工程师想维护 300 多个服务的组织,结果是一片混乱。

一旦跨过那条线,很多服务就没有清楚的负责人,或是负责人因为组织重组,接手了他们完全没有脉络的服务。你也会花更多时间在更新所有 repo 的依赖包,好清掉漏洞。要把微服务做好,你需要一个专职的平台团队,以及对工具的大量投资。多数初创根本没有资源去建那套基础设施,于是号称「敏捷」的架构,变成了维护的噩梦。

3. 哪个适合你?

别因为流行就选某种架构。要因为它能解决你当前的问题才选。趋势不该进到决定里。

符合以下情况,选微服务:

符合以下情况,选单体架构:

4. 务实之路:模块化单体与逐步拆分

这里有个秘密。你不必直接跳到微服务。很可能也不该跳。

模块化单体是很棒的折中。你建一个可部署的单元,但内部在模块之间设下严格的界线。Module A 的代码不能直接 import Module B 的代码,必须通过定义好的公开接口。这样你得到微服务的代码组织好处,却没有基础设施的开销。

随着应用程序成长,你可以把需要独立的部分剥下来。

如何演进:

  1. 找到接缝: 找出应用程序里像独立产品一样运作的部分。「用户认证」或「图片处理」都是常见的候选。
  2. 抽出,不要重写: 把那段代码移进另一个服务。它还是可以共用常见的函数库,例如你的 logging 或 metrics 设置,好维持一致性。
  3. 逐步迭代: 不要一次全拆。也许你只需要一个主要的单体,外加两个为特定任务准备的小型微服务。
  4. 小心共用代码: 在服务之间共用数据库表格是陷阱。服务一旦拆分,原则上就该拥有自己的数据。

图:混合做法

Hybrid Architecture Diagram

结论

微服务对单体架构的争论,常常抓错重点。重点不是哪种架构在理论上比较优越,而是你现在能忍受哪一组取舍。

从结构良好的单体开始。等痛感出现再拆,别提早动手。未来的你,还有你的 DevOps 团队,都会感谢你。

© Melvin Laplanche - All rights reserved.