欧阳亮的博客

编程不止是一份工作,还是一种乐趣!!!

《微服务架构》:服务粒度

微服务架构下,总是会有人问:服务最好应该切分到什么粒度?类似的问题还有:我们的程序应该拆分为多少个才合适?这类问题永远没有一个标准的正确答案,我们需要基于业务、可用性、弹性和成本等方面做一些综合的权衡,才能决定系统是否应该被组合成一个大而整的应用,还是拆分成多个小服务。过份的拆分可能会导致高额的成本和低微的回报。


修改的频率


如果一个单体应用中某个模块、或某个服务中的子上下文,频繁发生变更,那么将这些模块或上下文切分为独立的服务,可以最小化其对系统中其它部分的影响,比如:发布窗口、代码管理、故障隔离等等。


团队规模


小而精的团队可以更好的胜任功能独立且高频变化的服务,这会给他们更好的归属感,增加专业化程度。另外,团队的规模也决定了是否应该切分服务,规模越大,团队的协调成本就越高,越需要切分团队来减少沟通协作成本。


专业化技能


一些服务可能需要和其它团队不一样的开发技能。比如系统中搜索模块使用了ES,推荐模块使用了特定语言实现的特殊算法。擅长这些工作的工程师比起其它成员会有完全不同的技能树,把这些服务切分开来是有利的,从另一个维度减小团队间协调的成本。


上游服务


微服务外部与内部的世界是以微服务边界上下文划分的,在将一个较大的服务拆分成更小的服务前,需要评估上游系统如何使用我们的服务,以及拆分后对上游系统的影响。比如我们有一个粗粒度的客户服务,提供了客户资料、账号、等级、账户等子服务。当我们想把账户从客户服务中拆分成独立的服务时,需要考察上游系统是如何使用当前的客户服务的。如果客户服务提供了一个大接口,同时返回资料和账户信息,拆分之后谁来负责服务的编排?由调用方自己编排?如果有大量的调用方依赖呢?如果由客户服务负责编排,那当把等级、账号也切分为子服务呢时,又会导致客户服务本身偶合过多的业务,拆分的意义就不大。还是说引入一个API Gateway层?这些都是需要考虑的因素。


扩展性


一个服务中有几个相对独立的子上下文,如果某个上下文可能需要在高峰时应对短时间的访问爆发,而另一个上下文需要满足稳定的、渐近式的增长,那应该考虑把它们切分成不同的服务,而不需要设计一个解决方案来同时满足两者。


可靠性


服务的粒度越大,故障发生时带来的影响面也越大,识别出系统中脆弱的部分将其拆分出去,可以有效的减少故障时带来的连带影响。


成本


如果服务的耦合度很高,可能需要几个月去拆分他们,这样的代价是否值得,切分之后我们得到了什么?付出了多大的代价?