微服务拆分(1)
继上文提出“微服务边界如何划分”的问题后,后台有不少朋友留言,我也拉群组跟大家进行了相关讨论,总结如下:
- 使用微服务后,随着需求不断复杂化,微服务间边界越发不清晰,层次越发复杂,耦合日益严重,循环依赖问题比比皆是,以至于后期干脆直接推到重构;
- 系统边界的划分,是架构师经验不断累积后的本能行为,不具有什么可言传性。
整个讨论在大家吐槽完后,就没有结果地结束了。但事后仔细想想,我纠结的地方无非就是两个:
- 1.服务的粒度如何划分,就如同上文中的案例一样,借款模块和还款模块是否应该划分在同一个模块中?
- 2.服务间循环依赖、双向依赖的问题,应该如何避免。
对于第一个问题,是一个无法度量的问题,粒度多细才是细,多粗才算粗,根本就是你说了算,而且,很多时候,并非够细或够粗就是好事情。
- 当服务粒度过细时,服务间的层次结构会更复杂,进行编码时往往需要去对多个服务进行修改才能完成一个需求,这对于开发人员是一种很反感的体验。
- 当服务粒度过细时,对系统部署是极大的考验。微服务给我们带来了分布式系统享有的好处,同时也带来了运维、部署难度增加的坏处。现在我们的服务不过10+,已经有同学开始抱怨部署太复杂。(当然,很大程度是因为我们没有发布系统)
- 当服务粒度过粗时,服务内部的代码容易产生耦合。如果多人开发同一个服务,很多时候因为耦合会造成代码修改重合,开发成本相对也较高
对于粒度的划分,李运华老师提出了以项目组开发人员的数量来划分粒度的想法,我觉得很认同。一个服务,应该以2-3个人(可以根据团队成员构成进行分组,以组概念来权衡数量)来维护比较妥当。也就是说,如果整个团队有5个人,服务数量应该控制在2-3个以内。当服务日渐复杂时,我们可以化整为零,分而治之。而拆分系统相对来说,比整合系统要更加简单(因为可以很好地找到服务边界)。
第二个问题,服务间的复杂依赖关系如何管理。其实我们只要遵循一个基本原则:永远只有不同层级的单向依赖,就能让系统有一个清晰的依赖关系,因为单向永远不可能形成环状。也就是,高层服务可以依赖低层服务,同层服务间不互相依赖。如果出现了同层服务间依赖,就说明服务分层出现了问题,此时需要抽象出一个更高层次的服务或者提升其中一个服务的层次。