电子书/凤凰架构

11 / 77

边界:微服务的粒度

约 0.2 万字 · 0 阅读

子贡问:“师与商也孰贤?” 子曰:“师也过,商也不及。” 曰:“然则师愈与?” 子曰:“过犹不及。”

子贡问:“颛孙师和卜商谁更贤德?” 孔子说:“颛孙师常常作得有些过头,卜商常常达不到要求。” 子贡说:“如此说来,是不是颛孙师要好一些呢?” 孔子说:“过头和达不到同样不好。”

系统设计是一种创作,而不是应试,不可能每一位架构师设计的服务粒度全都相同,微服务的大小、边界不应该只有唯一正确的答案或绝对的标准,但是应该有个合理的范围,笔者称其为微服务粒度的上下界。我们可以分析如果微服务的粒度太小或者太大会出现哪些问题,从而得出服务上下界应该定在哪里。

可能是受微服务名字中“微”的“蛊惑”,笔者听过不少人提倡过微服务越小越好,最好做到一个 REST Endpoint 就对应于一个微服务,这种极端的理解肯定是错误的,如果将微服务粒度定的过细,会受到以下几个方面的反噬:

  • 从性能角度看,一次进程内的方法调用(仅计算调用,与方法具体内容无关),耗时在零(按方法完全内联的场景来计算)到数百个时钟周期(按最慢的虚方法调用无内联缓存要查虚表的场景来计算)之间;一次跨服务的方法调用里,网络传输、参数序列化和结果反序列化都是不可避免的,耗时要达到毫秒级别,你可以算一下这两者有多少个数量级的差距。远程服务调用里已经解释了“透明的分布式通信”是不存在的,因此,服务粒度大小必须考虑到消耗在网络上的时间与方法本身执行时间的比例,避免设计得的过于琐碎,客户端不得不多次调用服务才能完成一项业务操作,譬如,将字符串处理这样的功能设计为一个微服务便是不合适的,这点要求微服务从功能设计上看应该是完备的。

  • 从数据一致性角度看,每个微服务都有自己独立的数据源,如果多个微服务要协同工作,我们可以采用很多办法来保证它们处理数据的最终一致性,但如果某些数据必须要求保证强一致性的话,那它们本身就应当聚合在同一个微服务中,而不是强行启用XA 事务来实现,因为参与协作的微服务越多,XA 事务的可用性就越差,这点要求微服务从数据一致性上看应该是内聚(Cohesion)的。

  • 从服务可用性角度看,服务之间是松散耦合的依赖关系,微服务架构中无法也不应该假设被调用的服务具有绝对的可用性,服务可能因为网络分区、软件重启升级、硬件故障等任何原因发生中断。如果两个微服务都必须依赖对方可用才能正常工作,那就应当将其合并到同一个微服务中(注意这里说的是“彼此依赖对方才能工作”,单向的依赖是必定存在的),这条要求微服务从依赖关系上看应该是独立的。

综合以上,我们可以得出第一个结论:微服务粒度的下界是它至少应满足独立——能够独立发布、独立部署、独立运行与独立测试,内聚——强相关的功能与数据在同一个服务中处理,完备——一个服务包含至少一项业务实体与对应的完整操作。

我们再来想想,如果微服务的粒度太大,会出现什么问题?从技术角度讲,并不会有什么问题,每个能正常工作的单体系统都能满足独立、内聚、完备的要求,世界上又有那么多运行良好的单体系统。微服务的上界并非受限于技术,而是受限于人,更准确地说,受限于人与人之间的社交协作。《人月神话》中最反直觉的一个结论是:“为进度给项目增加人力,如同用水去为油锅灭火”(Adding Manpower to A Late Software Project Makes It Later)。为什么?Fred Brooks 给出了简洁而有力的答案:

有了以上铺垫,你应该更能理解前面的许多文章中笔者为何采用“2 Pizza Team”作为微服务团队规模的“量词”了,并不是因为制造这个梗的人是Jeff Bezos,是亚马逊 CEO、世界首富。而是因为两个 Pizza 能喂饱的人数大概就是 6-12 人,符合软件开发中团队管理的理想规模。

康威定律约束了软件的架构与组织的架构要保持一致,所以微服务的上界应该与 2 Pizza Team 能够开发的最大程序规模保持一致。2 Pizza Team 能开发多大规模的程序?人员数量固定的前提下,这个答案不仅与开发者的能力水平相关,更是与研发模式和周期相关。如果你的软件产品是瀑布开发,可能需要一个月、两个月迭代一次;如果采用 Scrum,可能会一周、两周完成一次冲刺;如果追求日构建、精益,甚至可能一天、两天就会集成构建出一个小版本,以上不同的研发方法,都会产生相应规模的上界。

综合以上,我们得出了第二个结论:微服务粒度的上界是一个 2 Pizza Team 能够在一个研发周期内完成的全部需求范围。

在上下界范围内,架构师会根据业务和团队的实际情况来灵活划定微服务的具体粒度。譬如下界的完备性要求微服务至少包含一项完整的服务,不超过上界的前提下,这个微服务包含了两项、三项业务操作是否合理,那需要根据这些操作本身是否有合理的逻辑关系来具体讨论。又譬如上界要求单个研发周期内能处理掉一个微服务的全部需求,不超过下界的前提下,一个周期就能完成分属于两个、三个微服务的全部需求时,是缩短研发周期更合理,还是允许这个周期内同时开发几个微服务,也可以根据实际情况具体讨论。

本文转载自开源项目 凤凰架构(作者 周志明(icyfenix)),按 CC BY-NC-SA 4.0(文档)/ Apache 2.0(代码) 许可刊载,正文未改动。

医疗、法律、政策类内容仅供参考,具体以当地部门、医生、律师的说法为准。