美国计算机科学家,LaTex的作者Leslie Lamport说:“分布式系统就是这样一个系统,系统中一个你甚至都不知道的计算机出了故障,却可能导致你自己的计算机不可用。”一语道破了开发分布式系统的玄机,那就是它的复杂与不可控。所以Martin Fowler强调:分布式调用的第一原则就是不要分布式。这句话看似颇具哲理,然而就企业应用系统而言,只要整个系统在不停地演化,并有多个子系统共同存在时,这条原则就会被迫打破。盖因为在当今的企业应用系统中,很难寻找到完全不需要分布式调用的场景。

服务的拆分

首先我们应该知道一个概念,服务拆分是对系统而言,是通过某个维度(一般是系统高可用)去做到服务责任单一,比方说,商城系统有详情页,订单等模块,对于大型商城,详情页的读多写少,这个时候可以做成一个微服务。原则是拆分粒度应该保证微服务具有业务的独立性和完整性,服务的拆分围绕业务模块进行拆分。服务的拆分围绕业务模块进行拆分是一种理想状态下的拆分方法,换句话说,我们在架构设计之初就假定我们可以掌握一切。然而,不同的服务可能由不同的团队开发与维护,实际场景下,微服务的便利性更多的在于团队内部能够产生闭环,换句话说,团队内部可以易于开发与维护,便于沟通与协作,但是对于外部团队就存在很大的沟通成本与协作成本。现在,我们来看一个案例。团队A 考虑到功能的复用性而开发了一个“互动组件”,其中包括 “评论模块”功能。此时,团队 B 并不知情也开发了一个类似的“互动组件”。而团队 C也有这个需求,它知道团队 A 有这个“互动组件”,希望可以复用,但是由于这个“互动组件”在设计的时候更多地考虑了团队 A的当前业务,没有很好的复用性,例如不支持“评论盖楼”功能,而由于团队 A 出于当前其他项目的进度原因无法马上提供支持,团队 B评估后决定花一周时间自己开发一个符合自己业务需求的“互动组件”。此时,各个项目团队各自维护了一个“互动组件”。此外,我们再来看一个案例。一个OA系统拥有“用户管理”、“文件管理”、“公告管理”、“政策管理”、“公文管理”、“任务管理”、“审批管理”等功能,如果按照微服务架构思想可以围绕业务模块进行拆分,但是事实上这个OA 系统的最终用户只有 30多人,使用微服务架构可能有点“杀鸡用牛刀”的感觉了。回顾下,第一个案例中,由于团队之间的职责与边界导致了服务的复用存在局限性,甚至造成各自为战的局面,这种情况一般需要公司层面进行规划和统筹。第二案例中,由于用户量不大,系统也不复杂,使用微服务反而带来了不必要的设计和运维难度,同时也带来了一些技术的复杂度。此外,我们还需要考虑服务依赖,链式调用、数据一致性、分布式事务等问题。

总结下,服务的拆分是一个非常有学问的技术活,要围绕业务模块进行拆分,拆分粒度应该保证微服务具有业务的独立性与完整性,尽可能少的存在服务依赖,链式调用。但是,在实际开发过程中,有的时候单体架构更加适合当前的项目。实际上,微服务的设计并不是一蹴而就的,它是一个设计与反馈过程。因此,我们在设计之初可以将服务的粒度设计的大一些,并考虑其可扩展性,随着业务的发展,进行动态地拆分也是一个不错的选择。