微服务的拆分原则与过程实践

1,462 阅读4分钟

「这是我参与2022首次更文挑战的第10天,活动详情查看:2022首次更文挑战

本章主要针对微服务的开发实进行梳理和总结,主要解决在迭代过程中,微服务拆分的时机一些原则和实践过程的步䠫,便于后续时机项目中已做参考,此次分享大纲如下分为两篇进行阐述,这是第2篇,第一篇请参考《微服务拆分的必要性和时机选择》:

拆分

拆分的原则

定义拆分过程中需要遵守的原则和规范,如下图,五大规范 image.png

原则一:遵守微服务能力边界定义

  • 微服务要遵守单一职责原则,从业务上定义每个微服务的业务能力
  • 微服务之间低耦合,每个服务解决不同的业务问题,没有模糊地带 image.png

原则二: 微服务之间单向依赖

微服务之间严禁循环依赖,双向依赖(往往大泥球的项目就是这么来的);微服务之间需要做到单向依赖 image.png

原则三:微服务之间交互方式遵循上下游关系

  • 定义微服务上下游关系
  • 下游系统可以直接依赖上游系统
  • 上游系统的行为对下游系统产生影响,需要通过领域事件的方式来实现 image.png

原则四:最小共享数据原则

  • 跨上下文仅保留引用信息
  • 快照、日志等数据可以冗余(需要保证冗余数据不变性) image.png 很多时候在拆分过程中因为业务的聚合查询,很难理清楚应该如何隔离和拆分,这里需要注意分析和选型

原则五:接口不同时操作跨上下文数据

  • 写操作:一次更新操作不能同事操作两个以上的上下文数据
  • 读操作:每个服务只返回属于自己业务上下文的数据;针对前端你的数据适配放到BFF(Backend for frontend,服务于前端的后端)处理,《BFF避坑指南

拆分的实施步䠫

步䠫一:调整代码结构,分析模块间依赖

将既有工程拉分支,根据业务与上下文划分代码,通过工具分析代码依赖关系(可以采用Idea中的时序图插件,非常好用)整理分析结果设计解决方案;拆分对象为和重点梳理点

  • 一个决和的代码直接访问另一个决和的代码或数据表
  • 单元测试代码混杂在一起
  • 跨聚合查询的SQL语句 image.png

步䠫二:架构重构,测试保护先行

补充高价值的测试,保护业务逻辑:

  • 契约测试
  • 接口级别的测试组件 加的Scope是什么?
  • 重点加第一步分析结果中依赖严重的逻辑 image.png

步䠫三:消除业务代码依赖

拆分的主要工作理清业务边界,消除业务代码的依赖,主要有如下的代码需要处理

  • 位置不正确的代码:需要迁移到对应的上下文中
  • 数据库实体嵌套的代码:改为通过接口调用访问另一个上下文的数据
  • 一个API访问了两个上下文的数据:改为增加一个新的包来分别调用不同的上下文接口来实现,后面迁移到BFF中
  • 直接访问另一个上下文数据表或函数:改为通过接口访问后面需要抽成API
  • 枚举、工具类、Exception等:复制到两个不同上下文的代码中
  • 跨聚合的SQL查询:这个是最为严重的也是最难处理的,最好是迁移到BFF中实现,或是通过数据聚合方式实现

步䠫四:分离单元测试代码

image.png

步䠫五:跨业务上下文SQL查询和信息冗余处理

image.png

步䠫六:服务拆分,跨服务接口上升到BFF,引入Toggle

建议实施步䠫如下,切不可急于求成

  • 抽取跨服务代码
  • 跨服务代码提到BFF,加Toggle做路由
  • 拆分独立服务,通过Toggle切流量
  • 待功能稳定后,删除旧服务中的代码 image.png

步䠫七:数据拆分

  • 数据表归类:数据表按上下文划分
  • 解除不必要的数据表关联:跨上下文插叙你的SQL
  • 物理上拆分:数据库拆分

image.png

总结与心得

在面对业务和技术的同时,我们应该如何正确的判定服务的拆分是否合理,这里没有标准答案,需要根据主导者自己的判断进行权衡;差分过程中技术实现难度复杂度大,工作量也不小,除了从技术测解决是否还有其他途径

个人心得:微服务拆分————早识别,早准备,等时机,一鼓作气image.png

最后总结

image.png