原文题目: Untangling Microservices, or Balancing Complexity in Distributed Systems
原文地址
翻译: 祝坤荣
微服务的蜜月期曾经完结了。Uber 正在将成千记的微服务重形成一个更加可治理的计划[1];Kelsey Hightower 正在预测单体架构将是将来[2];Sam Newman 甚至申明微服务不应该是第一抉择,而应该是最初一个抉择[3]。
这是怎么回事?只管微服务承诺了简略和灵便,为什么这么多的我的项目变得难以保护?或者难道最终单体架构更好?
在这篇文章中,我想要探讨这些问题。你会看到一些将微服务编程一团分布式大泥球的常见设计问题 – 当然,也会看到如何防止他们。
但最开始,让咱们先理解下什么是单体架构。
单体架构
微服务始终是被认为是单体利用代码的解决方案。然而单体利用是不是一个问题呢?依据维基百科的定义 [4],一个单体利用是自蕴含且与其余计算利用独立的。与哪些其余利用独立呢?这不是咱们在设计微服务时谋求的吗?David Heinemeier Hansson[5] 指出了单体利用的缺点。他
因而,微服务不是“修复”单体利用。微服务须要解决的真正问题是交付业务指标的有力。个别,团队是因为指数级增长的 – 或更糟的不可预测性 – 进行变更的老本才交付不了业务指标的。换一句话说,零碎不能满足业务的须要。不可控的变更老本不是单体利用的个性,而是大泥球的个性[6]:
大泥球是芜杂的构造,无序,泥泞,缠在一起的电线和胶带,面条代码的丛林。零碎显示出无节制增长,反复,长期修复的显著迹象。零碎中凌乱的将信息在很多极长链路的零碎局部中共享,这示意大部分重要信息都变成了全局的或被反复复制的。
对大泥球的复杂性的批改和进化能够因为多个起因引起:协调泛滥团队的工作,非功能性需要的抵触,或一个简单的业务域。无论怎样,咱们常常试图将这种简单问题分解成微服务来解决。
微什么?
文字“微服务”指明了服务的一部分能够被度量并且它的价值应该是最小化的。但微服务到底意味着什么?咱们看下一些常见的用法。
微团队
第一个工作在服务上的团队大小。而这个尺度能够按披萨来度量。你没听错。他们说如果工作在服务上的团队能够被 2 个披萨喂饱,那么这就是微服务。我发现这很有启发,我已经做一个我的项目而团队能够被一个披萨喂饱 … 而我敢对任何人说这团大泥球是微服务。
微代码库
另一种宽泛应用的办法时基于它的代码库来设计微服务。有些人将这个概念施展到了极致,将服务的大小限度到了某些确定的代码行数。就是说,能够形成一个微服务的确切代码行数还没被找到。当这个软件架构的圣杯被发现,咱们会进入下一个问题 – 构建微服务团建的编辑器宽度是多少?
有个更重大的问题,这个办法一个没那么极其的版本更风行。代码库的大小常被用来决定它是否是一个微服务。
某些时候,这个办法管用。更小的代码库,更小的业务域。因而,这容易了解,实现,倒退。而且,更小的代码库不太可能变成一个大泥球 – 如果产生了,也比拟容易重构。
可怜的是,后面提到的简略只是一个错觉。当咱们开始基于服务自身来评估服务的设计时,咱们疏忽了零碎设计的外围局部。咱们遗记了 零碎 本人,服务作为零碎的 组成。
“有很多有用和有启发性的办法来定义一个服务的边界。大小是最不重要的局部。”– Nick Tune
咱们开发零碎!
咱们开发零碎,而服务的汇合。咱们应用基于微服务的架构来优化零碎的设计,而不是设计独立的服务。无论他人怎么说,微服务不能,也永远不会齐全解耦,和独立。你不能打造用齐全独立的组件来打造零碎! 当初咱们看下“零碎”的定义[7]:
- 一组连贯在一起并可一起操作的物件或设施
- 一组为了一个特定目标一起应用的计算机设备或程序
服务会与其余服务进行一直交互来造成零碎。如果你通过优化服务来设计一个零碎,却疏忽了他们之间的交互,最终你可能是这样的终局:
这些“微服务”可能本身很简略,但零碎却变成了复杂性的天堂!
所以咱们如何不只是解决了服务的复杂性,而是也思考了整个零碎的复杂性来进行微服务设计呢?
这是个艰难的问题,但侥幸的是,在很早以前就有答案。
零碎视角的复杂性
四十年前,还没有云计算,没有寰球规模的需要,不须要每 11.7 秒部署一次零碎。但工程师依然须要控制系统复杂度。只管这些工具与当初不一样,但挑战 – 更重要的是,解决方案 – 都是相似的,也能够被用于基于微服务设计的零碎。
在他的书里,“组合 / 结构设计”[8],Glenford J. Myers 探讨了如何用结构化的过程代码来升高复杂度。在书的第一页,他写到:
对于复杂性的主题中有比简略的尝试最小化程序中一部分的本地复杂度更重要的事。一个更重要的复杂度类型是全局复杂度:程序或零碎的全局构造的复杂度(比方,程序次要局部的关联或独立水平)。
在咱们的语境里,本地复杂度就是每个独立微服务的复杂度,而 全局复杂度是整个零碎的复杂度 。本地复杂度以来与一个服务的 实现局部 ;全局复杂度是被服务间的 交互和依赖 所定义的。
所以哪一个复杂度更重要 – 本地还是全局?让咱们看看当只有一种复杂度被关怀时的状况。
要将全局复杂度降到最小理论非常简单。咱们只有评估下任何零碎组件间的交互 – 即,将所有性能在一个单体服务中实现。就像咱们早前看到的,这个策略在某些特定场景是有用的。而在其余场景,它会导致恐怖的 大泥球 – 可能是最高级别的本地复杂度。
从另一方面,咱们很分明当你只优化本地复杂度而漠视零碎全局复杂度时会产生什么 – 更大的 分布式大泥团。
因而,当咱们只关注复杂度的某一种,选哪一个并不重要。在一个简单分布式系统,对向的复杂度都会暴涨。所以,咱们不能只优化一个。相同,咱们要均衡本地和全局复杂度。
有意思的是,在“组合 / 结构设计”一书中形容的复杂度均衡不仅与分布式系统无关,其也提供了如何设计微服务的见解。
翻译待续 …
援用索引
- Gergely Orosz’s tweet on Uber
- Monoliths are the future
- Microservices guru warns devs that trendy architecture shouldn’t be the default for every app, but‘a last resort’
- Monolithic Application(Wikipedia)
- The Majestic Monolith – DHH
- Big Ball of Mud(Wikipedia)
- Definition of a System
- Composite/Structures Design – book by Glenford J. Myers
本文来自祝坤荣 (时序) 的微信公众号「麦芽面包,id「darkjune_think」
开发者 / 科幻爱好者 / 硬核主机玩家 / 业余翻译
微博: 祝坤荣
B 站: https://space.bilibili.com/23…
交换 Email: zhukunrong@yeah.net
转载请注明。