“把所有东西都拆分成微小的、独立的服务,独立扩展团队,部署更快、行动更快。”
但最近,发生了一些奇怪的事情:那些迁移到微服务的团队,现在正回归到单体架构。
而且不只是小创业公司——亚马逊、Shopify、Basecamp、Segment,甚至谷歌也在这么做。
没错。这些开创微服务的公司正在悄悄承认:
“我们做得过头了。”
等等……微服务有什么问题?
老实说,微服务听起来很棒。理论上,它们有着这样的优势:
独立部署
可扩展的团队
清晰的职责分离
但现实中你常常得到的是:
成百上千个没人理解的小仓库(repo)
因过多网络通信导致的延迟问题
开发人员花在基础设施上的时间比产品还多
“这鬼问题到底出在哪?”
如果你真的用微服务构建过任何实际的东西,你可能亲身体验过这些。
一个简单例子
假设你正在构建一个电商系统。
使用微服务,你可能会这样拆分:
认证服务(auth-service)
目录服务(catalog-service)
购物车服务(cart-service)
订单服务(order-service)
通知服务(notification-service)
挺酷吧?
但接着……
你引入 Kafka 或 RabbitMQ 来把它们粘合在一起
你需要 Redis 来共享会话
你的 CI/CD 需要 30 分钟来部署所有服务
你开始编写只是为了与其他代码通信的代码
猜猜结果如何?
现在,你想构建的那个“简单”功能需要在 5 个服务中修改,提交 3 个拉取请求(PR),并经过 2 个团队的批准。
微服务放大了复杂度
这是当时我们没有完全承认的部分:
微服务不会减少复杂性——它们只是把复杂性转移了地方。
在单体架构中,复杂性在代码里。而使用微服务时,复杂性无处不在:
网络延迟
API 契约(接口约定)
数据一致性
部署流水线
服务发现
日志记录、追踪、监控指标
问问任何资深开发者:维护 50 个“微小”的 Go 服务比维护一个结构良好的大型单体应用要难。
为何单体架构正卷土重来
单体架构更简单。不是“更容易”,而是活动部件更少。
在单体架构中:
所有东西都在一个地方
调试直截了当
代码修改是原子性的(整体性)
没有跨服务的 API 噩梦
本地开发无需 Kubernetes
而且借助 Go、Rust、Deno 等工具以及现代部署实践(Docker、k8s),单体架构也能很好地扩展。
现实案例:Shopify 和 Segment 回归了
Shopify:曾全面投入微服务。现在呢?正在积极迁移回一个模块化单体架构。
Segment:情况相同。在经历了规模、延迟和团队速度的挣扎后,写了一篇题为《告别微服务》的博客文章。
即使是微服务的鼻祖亚马逊也承认,只有在你先解决了其他 100 件事情之后,这种模型才行得通。
模块化单体:两全其美?
这是现在许多公司正在采用的方式。
他们不再构建一团乱麻的大单体,而是构建:
一个单一的可部署单元
具有清晰的内部边界
像微服务一样组织,但运行在一个进程中
你依然能获得职责分离,但没有网络跳转、复杂的工具链或部署痛苦。
在 Go 语言中,你只需按包(package)或领域(domain)拆分:
/cart
/order
/notification
但它仍然是一个应用。
那么……我们应该抛弃微服务吗?
不一定。在以下情况它们仍然有意义:
你确实达到了规模(数百万用户)
你有多个产品团队在以极快速度推进
你已经完善解决了你的可观测性和部署流水线
但如果你是:
工程师少于 50 人
专注于一个产品
花在基础设施上的时间比功能开发还多
那么是的!单体架构可能真的能拯救你的团队。
最后思考
技术趋势如浪潮般起伏,我们对微服务用力过猛了,现在我们正需要回摆。
不要追逐潮流,选择能让你的团队更快、更从容、更高效的方案。
有时,最好的架构不是最时髦的那个,而是能让你晚上睡得安稳的那个。
如果字段的最大可能长度超过255字节,那么长度值可能…
只能说作者太用心了,优秀
感谢详解
一般干个7-8年(即30岁左右),能做到年入40w-50w;有…
230721