拆代码之前,先想好怎么拆客户
银行要隔离和季度更新,零售商要新功能尽快上线,这时部署标记比微服务更关键。

要点速览
- 微服务能提升应用的容错能力,但满足不了个别客户要求数据独立或放慢更新这类需求。
- 把多个任务塞进同一个计算单元很省钱,但这些任务从此共享发布节奏、故障域和安全上下文。
- 部署标记能把客户分组隔离,代价是基础设施大幅增加,租户在标记之间迁移也非常困难,所以从第一天起就需要基础设施即代码。
设想你要把同一套方案交付给七个客户:一家银行和六家中型零售连锁。银行不希望自己的数据和别人的放在一起,而且每季度只接受一次更新。零售连锁则希望新功能越快上线越好。
工程团队面对架构,第一个问题往往是选单体还是微服务。对前线部署工程师(FDE)来说,更重要的问题是怎么拆分客户:谁共享基础设施,谁拿到专属副本,谁在什么时候收到更新。
微服务拆的是代码,部署标记拆的是客户。把两者混为一谈,结果就是系统很贵,却依然满足不了最挑剔的那个客户。
微服务解决的是另一个问题
AWS 介绍微服务时强调了一个明确的好处:服务之间相互独立,应用的容错能力更强。这个好处是真实的,但有代价。早在 2014 年,Martin Fowler 就指出,分布式事务出了名地难做对。
Fowler 的建议也很务实:先从单体开始,保持模块化,等单体开始带来问题时再拆成微服务。这很适合 FDE 的工作场景:人手通常不多,时间很紧,系统得先在客户环境里跑起来,才轮得到讨论架构是否优雅。
也有一个常被引用的数字指向相反方向。据 DevClass 在 2023 年 5 月的报道,Amazon 的一份内部案例研究显示,负责监控音视频质量的 Prime Video 团队把分布式组件合并成单个进程,基础设施成本下降了 90% 以上。
这个结果只适用于该团队自身的情况,但它提醒我们:拆分从来不是免费的。
回到开头那家银行。把系统拆成 12 个服务,它的两项要求一项也满足不了。
即便有 12 个服务,银行仍然和其他所有客户共用一个数据库、一套发布计划。
合并计算很便宜,但一切都绑在一起
Azure 架构中心有一个模式,和单体“合并以省钱”的思路相近:计算资源整合(Compute Resource Consolidation),即让多个任务共享计算资源以降低成本。这个模式关注的是任务如何在基础设施上运行,而不是代码如何组织,但它清楚地展示了合并的代价。
按照该文档的说法,更新一个任务,就得停止、重新部署并重启同一计算单元里的所有其他任务;合并后的任务还共享同一个故障域和安全上下文。
同一份文档指出,处理高度敏感或隐私数据的任务不应合并,因为它们需要独立的安全上下文。放到面向多个客户交付的场景里,所有人都跑在一个整体中的局限就很明显了:它能一直用下去,直到第一个客户要求数据隔离。
即使保留单体,也有一个错误应当从一开始就避开。Microsoft 把所有数据塞进同一个数据存储列为反模式,因为这会造成资源争用、拖慢性能。建议是按数据的使用方式分开存放。
代码层面是单体,并不意味着所有数据只能放在一个数据库里。
部署标记:按客户拆分,而不是按功能拆分
部署标记从另一个方向解决问题。它不把应用拆成多个部分,而是部署整个应用的多个独立副本,每个副本有自己的数据存储。在多租户环境中,每个部署标记服务一组预先确定的租户。
Microsoft 描述的一个场景与 FDE 的工作非常接近:部分大客户可能需要专属实例,小客户则共享一个多租户部署。部署标记还能解决更新节奏问题。
有的客户接受频繁更新,有的客户厌恶风险、希望少更新,因此每个部署标记可以采用不同的部署环。
套用到开头的七个客户:标记 A 只服务银行,拥有独立的数据和安全上下文;标记 B 由六家零售连锁共用。
每个新版本先发到标记 B,平稳运行几周后,才进入标记 A。代码仍是模块化单体,变的只是部署方式。
| 标准 | 计算资源整合 | 微服务 | 部署标记 |
|---|---|---|---|
| 拆分轴线 | 不拆分;多个任务共享一个计算单元 | 按功能拆分代码 | 按租户组拆分客户 |
| 发布节奏 | 改一个任务就要重新部署整个单元 | 无法按客户设定节奏 | 每组客户有各自的部署环和节奏 |
| 敏感数据隔离 | 共享安全上下文,不适用 | 无法按客户解决 | 大客户可以有专属部署标记 |
| 主要代价 | 共享故障域 | 分布式事务难做对 | 基础设施大增,租户难迁移 |
| 适用场景 | 任务不需要独立的安全上下文 | 单体确实已经带来问题 | 客户在隔离或更新节奏上有差异 |
这张表很容易被读成三选一,其实不然。部署标记是一种部署方式,单体与微服务之争是代码组织方式,所以模块化单体完全可以跑在多个部署标记上,就像上面银行和零售连锁的例子。
每多一个副本都要花钱
Microsoft 对代价也说得很清楚:部署多份基础设施会显著增加运营成本。把租户从一个部署标记迁到另一个也很困难。因此,哪个客户放在哪个部署标记上,应当在客户调研阶段就慎重决定,而不是等客户已经进入生产环境再说。
运行多个部署标记,需要基础设施即代码和漂移控制。没有它们,每次有人在客户环境里手动改动,各个部署标记之间就会多分化一点。Microsoft 还建议至少部署两个部署标记,因为只有一个时,很容易把只在单实例下成立的假设写死在代码里。
反过来,部署标记也不是默认选项。按照 Microsoft 的说法,如果方案很简单、不需要大规模扩展,或者单个实例就能承担负载,就不应使用这个模式。如果你只有一个客户,或者所有客户都乐于共享,那么数据分得合理的模块化单体就够了。
客户要求数据留在特定区域时
还有一种选择:Geode 模式,其中每个实例都能服务任何用户,而不像部署标记那样只服务一组客户。Microsoft 表示,Geode 的设计和构建通常复杂得多,适合对数据位置没有限制的云原生平台。
所以在考虑 Geode 之前,先在一开始就问清客户对数据位置有没有要求。Microsoft 指出,在有数据驻留要求,或应用需要为会话保存临时状态的情况下,Geode 并不适用。
这些情况下,Microsoft 建议把部署标记与全局路由层结合,由路由层把请求导向正确的部署标记。
如果你的客户要求数据绝不离开某个区域(银行、医院或政府机构常有这种要求),答案几乎是现成的:每个区域一个部署标记,前面加一层路由。它在理论上未必最优雅,但你能向客户的合规团队讲清楚。
写给想做 FDE 的开发者
阅读 FDE 或解决方案工程师岗位的职位描述时,留意 multi-tenant、single-tenant deployment、dedicated instance 和 infrastructure as code 这类说法。它们说明公司正面临这类拆分客户的问题,需要同时理解两条架构轴线的人。
简历上不要只写“把系统迁移到微服务”。把你如何决定部署方式、为什么这么决定写清楚:哪些客户拿到了专属实例、原因是什么,发布节奏如何划分,又做了什么来防止各环境之间产生漂移。
一个权衡过取舍的决策故事,比一串技术名词有说服力得多。
面试中如果被问到“单体还是微服务?”,好的回答通常先反问:有多少个客户,他们之间有什么差异?在 FDE 岗位上,怎么拆客户往往比怎么拆代码更能决定项目的成败。
这篇文章对你有帮助吗?
感谢你的反馈!
7 个信源
- Deployment Stamps Pattern - Azure Architecture Center | Microsoft Learn · 2026-04-28
- Geode pattern - Azure Architecture Center | Microsoft Learn · 2024-03-18
- Compute Resource Consolidation Pattern - Azure Architecture Center | Microsoft Learn · 2026-04-08
- Monolithic Persistence Antipattern - Azure Architecture Center | Microsoft Learn · 2017-06-05
- Microservices · 2014-03-25
- Introduction to Microservices (AWS)
- Reduce costs by 90% by moving from microservices to monolith: Amazon internal case study raises eyebrows · 2023-05-05