DHH:如何从微服务中恢复?


我不否认在某些情况下微服务优先的架构很有意义,但我认为这种情况很少见。绝大多数系统都可以通过启动并保持在一个宏伟的单体中得到更好的服务。昨天引爆互联网的Prime Video 案例研究只是最新的例证。

也许一旦达到 Netflix 或亚马逊的规模,有些领域就开始有意义了,但请记住,即使是GitHubShopify这样的公司将他们的主要应用程序作为具有数百万行代码的单体运行,并有成千上万的程序员在它们上进行协作。

您是否有更多的数百万行代码或数千名程序员在相同的代码库上工作?如果没有,在考虑微服务之前要格外小心。

但这是对今天开始新系统的人们的建议。如果您已经过早地采用了微服务架构,您会怎么做?你如何恢复?这里有一些提示:

1)停止挖掘。
在你停止制造更多之前,你无法清理一团糟。

这意味着不引入新的微服务。这意味着选择一个现有的微服务作为承载新功能的中心。
这个新中心的引力最终也会吞噬大多数其他微服务,但最重要的是不要让事情变得更糟。

2) 首先整合关键的、依赖的路径。
最糟糕的微服务疯狂形式是当你把一个单一的、连贯的流程分割到多个系统中。也许这是注册,也许这是结账,也许这是访问一个单一的内容。这是微服务造成最大伤害的地方,因为它使更新整个流程变得繁琐和容易出错。做出改变意味着要在多个系统之间进行协调,处理同步问题,甚至更糟。因此,你在回到单体的路上把微服务变成宏服务的安慰应该从这里开始。

3) 最后留下孤立的性能热点。
当微服务做得很好时,它们通常针对系统中一个狭窄的、孤立的、通常是性能关键的部分,它可以从用更笨重但更快的编程语言重写中受益。也许你的整个网络应用都是用Ruby on Rails编写的,但有一个屏幕可以看到疯狂的负载高峰,而且由于某种原因不能被缓存,所以你就把Rust或Go或其他什么语言拉出来,以榨取CPU的所有能量。干得好,你的微服务很有成就感!(只是要确保你确实做了基准测试,以证明生产率的下降是值得的)。

4) 优先放弃最深奥的实施。
微服务疯狂的一个可怕的副作用是,人们倾向于接受一百万种不同的编程语言、框架和生态系统。微服务的诱惑唱出了高大上的隔离故事,让人联想到CIO的 "同类最佳 "的梦想,并勾起了程序员尽可能尝试新的和不同的自然倾向。

但最终的结果很可能是一个由3-5-7种不同的编程语言组成的系统,甚至更多不同的框架,以及一堆平行的依赖性轨道。这对概念的理解是致命的,并导致常见的微服务症状,即 "没有人理解或能够在整个系统上工作"。

因此,你必须开始修剪。绝大多数系统在任何时候都不应该有超过两种后端语言在发挥作用:一种是为程序员生产力而调整的通用语言,你可以在99%的时间内使用它,另一种是为解决最后1%的热点问题而调整的高性能语言,如果它们出现的话。

5) 学习用模块而不是网络来划分大型系统。
微服务的许多动机都是由这样的谬论驱动的:如果你不能弄清楚如何使用模块和命名空间等编程工具来正确地架构一个大系统,那么你可以通过用网络边界来分割它来解决这个问题?不,不,不。

制作一个大型的、有弹性的、有性能的系统是很难的。试图在第一天就为一个新的问题空间设计一个系统是不可能的。听从约翰-盖尔的永恒的建议:

一个有效的复杂系统总是被发现是从一个有效的简单系统演变而来的。反命题似乎也是正确的:从头开始设计的复杂系统永远不会工作,也无法工作。

简单性要求你不要一开始就邀请复杂的野兽--分布式系统--来跳第一支舞。有可能有一天你会拥有一个复杂的、分布式的系统,并有理由使用微服务,但这只有在你从一个简单的、单体的设计开始时才会发生。

研究如何将大型问题空间分解为漂亮的领域模型的关键著作是 Eric Evan 的领域驱动设计
但是,只有在你通过Kent Beck的《Smalltalk最佳实践》(如果你使用面向对象的语言)和Martin Fowler的《企业应用架构模式》等书掌握了战术性编程的基础知识之后,你才应该毕业于这个级别的战略和架构愿望。

我们的行业充满了聪明、热情的人。他们中的许多人在跑完5公里之前就急于开始铁人三项。尽管我很钦佩他们的魄力和自信,也不相信一般情况下的学习速度限制,但我也认为我们没有更早地明确微服务的危险性,这对他们中的很多人是一种伤害。

但这就是学习的好处:你总是可以开始!如果学习新的东西让你对之前的选择有不同的反思,那么你可以从今天起改变你的方法。

是的,微服务,像任何编程模式一样,是一种工具。是的,"这取决于 "在技术上是正确的。但是,我们仅仅说这句话并不能为那些希望设计更好的系统的人提供指导;我们需要愿意说出它取决于什么。仅仅说 "这取决于 "并不能帮助任何人做出更好的决定。

所以,让我们说清楚。使用好微服务通常取决于:

a) 拥有一个大型的、复杂的系统,并从一个小型的、简单的系统成功地演变而来。

b) 有能力在这个明确的模块化设计中找出一个有强大边界的部分,并且没有关键流程的依赖性,作为提取的候选者。
然后才着手进行,如果通过转换实施方法可以获得巨大的性能收益,
或者将该模块放在整个团队中可以获得组织上的好处,而该团队不容易与系统的其他制造者进行合作。

你很可能在你的系统或组织中找到其他的理由,但在着手进行微服务之前,应该清楚地阐述这些理由,严格地检查,并提出批评性的质疑。

或者,你知道的,把你的系统设计无谓地分割成几十块,然后在宿醉得够呛的时候再回到本指南。当你准备好享受它的简单和智慧时,这块雄伟的单体将永远在这里。选择你自己的冒险!

banq:本文第一句:
在某些情况下微服务优先的架构很有意义,但我认为这种情况很少见。
这句体现普通人的主语思维误区,当我们在盲人摸象阶段时,无法抉择:应该是微服务优先还是单体优先呢?
只有试错了以后才能确定,但是你不能吃了第三个包子饱了以后,后悔前面两个包子吃错了。
不想试错?那么你作为一个主语上帝,就是一个盲人摸象中的盲人,但是自以为看得很清楚,眉毛胡子一把抓,从单体开始。
因此,架构决策是否民主决定了你这两条路的选择,如果走试错的路,就从微服务开始,如果走主语上帝的路,从单体开始。