自从 2005年首次提出[1] 以来,采用微服务架构、单体服务架构还是两者之间的混合架构的争论,已经成为大多数工程组织做出的最难逆转的决定之一。即使迁移到不同的数据库技术,通常也比从单体应用迁移到微服务或从微服务迁移到单体应用的成本要低。
在许多方面,业界已经完成了一个完整的循环,从2010年代大多数超大规模公司进行多年的单体应用到微服务的迁移,到 Kelsey Hightower关于分布式单体应用危险的标志性推文[2] :
2020年预测:在人们发现分布式单体应用的缺点后,单体应用将重新流行起来。- @KelseyHightower
尽管普遍观点已经普遍转向反对微服务,但许多工程组织仍然两种方法都有一些,通常是一次或多次早期但不完整的迁移努力的残余。这个策略着眼于一个理论上的组织,它被两种方法都困住了,我们称之为理论合规公司,该公司正在寻求确定其未来的道路。
以下是理论合规公司的服务架构策略。
这是我正在 #eng-strategy-book[3] 中构思的一本关于工程策略的书的探索性草稿章节。因此,一些链接指向其他草稿章节,包括已发布的草稿和非常早期的未发布草稿。
阅读本文档
要应用这个策略,请从顶部的_政策_开始。要理解这个策略背后的思考,请按相反顺序阅读各个部分,从_探索_开始,然后是_诊断_,依此类推。相对于默认结构,本文档进行了两个方面的重构以提高可读性:首先,_操作_已被合并到_政策_中;其次,_完善_已被嵌入到_诊断_中。
关于这种结构的更多细节,请参阅 制作可读的工程策略文档[4] 。
政策
我们的服务架构政策记录在此。对此政策的所有例外必须上报给本地Staff级以上工程师以获得批准,然后与该Staff级工程师一起上报给CTO。如果您对这些政策有任何疑问,请在#eng-strategy
中询问。
我们的政策是:
业务部门应始终在自己的代码仓库和单体应用中运作。 他们不应该提供许多不同的服务。他们很少在其他业务部门的单体应用中工作。细节上有一些微妙之处:做出使我们更接近前面这句话为真的决定。
跨业务部门单体应用的新集成应使用gRPC完成。 这里强调的是_新的_集成;迁移使用其他实现(HTTP/JSON等)的现有集成是可取的,但不紧急。
当决策微妙时(例如对现有端点的更改),优化业务速度而不是技术纯粹性。当决策远非微妙时(例如全新的端点),遵守政策。除了新的业务部门单体应用外,我们不允许新的服务。 您应该在最合适的业务部门单体应用或现有的基础设施仓库中工作。提供新服务(除非它对应一个新的业务部门)总是需要在
#eng-strategy
中获得CTO的批准。
除非新服务需要与现有单体应用显著不同的非功能性要求,否则通常不会_批准_。例如,如果它需要在更改之前进行显著更高的合规性审查,如我们现有的支付服务,或者如果它需要显著更高的每秒请求数等。尽可能将现有服务合并到业务部门单体应用中。 我们认为,将现有服务移回单体应用的每个选择都应该"在细节中"而不是从自上而下的战略角度做出。因此,我们通常鼓励团队逐步关闭其业务部门单体应用之外的现有服务,但将决定权交给团队,以便他们根据本地环境做出正确的决定。
诊断
理论合规公司在拆解我们的单体应用方面有着复杂的历史。我们还在增加业务部门的数量,同时限制对核心业务部门的投资。这是一个复杂的时期,需要权衡许多约束。为了提高可读性,我们将诊断分为两个部分:"业务约束"和"工程约束"。
我们的业务约束是:
我们向其他公司销售企业对企业的合规解决方案,采用年度订阅制。有一个主要的、成熟的业务线,以及两个较小的部分验证的业务线,旨在附加到成熟的业务线以增加平均合同价值。
公司有2,000名员工。其中约500人在工程组织中。在这500人中,约150人从事最广义的"基础设施工程",如开发者工具、计算和编排、网络、安全工程等。
业务是盈利的,但收入增长一直是同比10-20%,这给我们的董事会带来了持续的支出压力,因为相对于公开市场的可比公司,我们的表现略低。除非我们能将同比增长提高5-10%,否则他们希望我们每年改善自由现金流5-10%,这危及我们维持长期基础设施投资的能力。
主要业务线的增长正在萎缩。 公司的战略包括启动更多相邻的业务部门,以通过新产品增加平均合同价值。我们需要在不增加总体预算的情况下为这些业务部门提供资金,这意味着新业务部门的预算必须从我们的核心业务或平台团队中抽调。
除了需要为新业务部门提供资金外,还有持续的压力要使我们的核心业务更加高效,这意味着要么加速增长,要么减少投资。在减少投资的同时加速增长是具有挑战性的,这表明大部分改进将来自减少我们的投资。我们将平台成本分配给业务部门的方法是按照每个业务部门创造的收入比例进行分配。我们的核心业务产生了大部分收入,这意味着它要承担大部分平台成本,即使这些成本是由新业务线驱动的。
这意味着,即使由于启动多个业务部门而增加了平台团队的负担,但由于它主要表现为核心业务的成本,我们必须提高其效率,因此在减少平台支出方面存在巨大的财务压力。这意味着我们几乎不能容忍任何增加基础设施开销的做法。
我们的工程约束是:
我们的基础设施工程团队有150名工程师支持350名产品工程师,可以肯定的是,在可预见的未来,基础设施不会显著增长。
我们在过去六个月内启动了两个新的业务部门,并计划在明年启动另外两个新的业务部门。每个业务部门由一名总经理领导,该业务部门内的工程和产品主要对该总经理负责。我们的CTO和CPO仍然制定实践标准,但在任何给定的辩论中,这些实践标准或来自总经理的指示是否是最后决定权,取决于具体情况。
例如,一个业务部门一直不愿意为他们的产品支持随叫随到的轮值,因为他们的总经理坚持认为这是一种浪费的做法。因此,即使他们的服务负责影响共享功能的稳定性,该团队也经常不响应页面。我们已经对 服务和单体应用如何随时间推移为产品和基础设施组织创造开销进行了建模[5] ,并确信,总的来说,基础设施支持更多服务会产生更多开销。我们还发现,在我们的组织中,由于团队重组导致的服务所有权变更率抵消了离开单体应用的大部分初始生产力收益。
前两个观察结果之间存在一些矛盾:通常来说,拥有更多服务会产生更多开销,但不负责任的业务部门破坏共享的单体服务会产生_更多_的开销。例如,我们可以更容易地限制来自行为不当的服务的使用率,而不是纠正共享服务中行为不当的代码路径。
我们还有一个支付服务,用于将资金从客户转移给我们。我们对这项服务变更的合规和安全要求显著高于大多数软件,因为其影响范围基本上是无限的。
我们的主要编程语言是Ruby,它通常依赖于阻塞IO,而面向服务的架构通常在阻塞IO上花费更多时间,而不是单体应用。同样,Ruby在序列化和反序列化JSON负载方面_相对_效率较低,而我们的服务架构需要这些作为跨服务通信的一部分。
我们之前尝试过拆分,并且有一些遗留的部分迁移,这些迁移与我们当前的业务部门所有权结构不完全一致。这些新服务的数量随着时间的推移继续增长,给当前的基础设施和未来的产品团队带来了更多的负担,因为他们试图在各种团队重组中维护这些服务。
探索
在2010年代后期,大多数大型或正在扩展的公司都在某种程度上采用了服务。很少有公司采用微服务,大多数采用者选择了 面向服务的架构[6] 。 Kelsey Hightower 2020年关于分布式单体应用危险的标志性推文[1] 捕捉到了一个逆转的开始,更多的公司认识到了运营面向服务架构的负担。
除了更广泛地认识到这些负担外,许多最初推动服务架构的云基础设施挑战也开始缓解。如今,大多数基础设施工程师_只_知道如何使用云原生模式进行操作,而不是从面向机器的方法开始。像PostgreSQL这样的标准数据库技术已经显著改进了功能。云提供商有快速的本地缓存,可以快速检索经过验证的上游包。云计算的供应和成本是可承受的。慢速编程语言比十年前更快。非类型化语言有合理的增量路径到类型化代码库。
由于这种转变,如果你看一个新兴的公司,它特别可能在一个后端和一个前端编程语言中有一个单体应用。然而,如果你看一个五年以上的公司,你可能会发现几乎任何情况。一种特别常见的情况是一个包含大部分功能的单体应用,以及分散在整个组织中的不一致的团队范围的宏服务星座。
从 零利率政策[7] 的转变也影响了趋势,因为面向服务的架构往往需要更多的基础设施来高效运行,例如服务网格、服务配置和取消配置等。经过适当调整,面向服务的架构应该具有成本竞争力,并可能在复杂工作负载中表现更优,但在削减成本的环境中很难维持对基础设施团队所需的投资。这鼓励新公司限制自己使用单体方法,并推动现有公司_尝试_逆转他们之前拆解单体应用的努力,结果喜忧参半。
参考链接
- 2005年首次提出: https://en.wikipedia.org/wiki/Microservices
- Kelsey Hightower关于分布式单体应用危险的标志性推文: https://x.com/kelseyhightower/status/940259898331238402
- #eng-strategy-book: https://lethain.com/tags/eng-strategy-book/
- 制作可读的工程策略文档: https://lethain.com/readable-engineering-strategy-documents
- 服务和单体应用如何随时间推移为产品和基础设施组织创造开销进行了建模: https://lethain.com/services-overhead-model/
- 面向服务的架构: https://aws.amazon.com/compare/the-difference-between-soa-microservices/
- 零利率政策: https://en.wikipedia.org/wiki/Zero_interest-rate_policy