「这是我参与2022首次更文挑战的第10天,活动详情查看:2022首次更文挑战」
本章主要针对微服务的开发实进行梳理和总结,主要解决在迭代过程中,微服务拆分的时机一些原则和实践过程的步䠫,便于后续时机项目中已做参考,此次分享大纲如下分为两篇进行阐述,这是第2篇,第一篇请参考《微服务拆分的必要性和时机选择》:
拆分
拆分的原则
定义拆分过程中需要遵守的原则和规范,如下图,五大规范
原则一:遵守微服务能力边界定义
- 微服务要遵守单一职责原则,从业务上定义每个微服务的业务能力
- 微服务之间低耦合,每个服务解决不同的业务问题,没有模糊地带
原则二: 微服务之间单向依赖
微服务之间严禁循环依赖,双向依赖(往往大泥球的项目就是这么来的);微服务之间需要做到单向依赖
原则三:微服务之间交互方式遵循上下游关系
- 定义微服务上下游关系
- 下游系统可以直接依赖上游系统
- 上游系统的行为对下游系统产生影响,需要通过领域事件的方式来实现
原则四:最小共享数据原则
- 跨上下文仅保留引用信息
- 快照、日志等数据可以冗余(需要保证冗余数据不变性)
很多时候在拆分过程中因为业务的聚合查询,很难理清楚应该如何隔离和拆分,这里需要注意分析和选型
原则五:接口不同时操作跨上下文数据
- 写操作:一次更新操作不能同事操作两个以上的上下文数据
- 读操作:每个服务只返回属于自己业务上下文的数据;针对前端你的数据适配放到BFF(Backend for frontend,服务于前端的后端)处理,《BFF避坑指南》
拆分的实施步䠫
步䠫一:调整代码结构,分析模块间依赖
将既有工程拉分支,根据业务与上下文划分代码,通过工具分析代码依赖关系(可以采用Idea中的时序图插件,非常好用)整理分析结果设计解决方案;拆分对象为和重点梳理点
- 一个决和的代码直接访问另一个决和的代码或数据表
- 单元测试代码混杂在一起
- 跨聚合查询的SQL语句
步䠫二:架构重构,测试保护先行
补充高价值的测试,保护业务逻辑:
- 契约测试
- 接口级别的测试组件 加的Scope是什么?
- 重点加第一步分析结果中依赖严重的逻辑
步䠫三:消除业务代码依赖
拆分的主要工作理清业务边界,消除业务代码的依赖,主要有如下的代码需要处理
- 位置不正确的代码:需要迁移到对应的上下文中
- 数据库实体嵌套的代码:改为通过接口调用访问另一个上下文的数据
- 一个API访问了两个上下文的数据:改为增加一个新的包来分别调用不同的上下文接口来实现,后面迁移到BFF中
- 直接访问另一个上下文数据表或函数:改为通过接口访问后面需要抽成API
- 枚举、工具类、Exception等:复制到两个不同上下文的代码中
- 跨聚合的SQL查询:这个是最为严重的也是最难处理的,最好是迁移到BFF中实现,或是通过数据聚合方式实现
步䠫四:分离单元测试代码
步䠫五:跨业务上下文SQL查询和信息冗余处理
步䠫六:服务拆分,跨服务接口上升到BFF,引入Toggle
建议实施步䠫如下,切不可急于求成
- 抽取跨服务代码
- 跨服务代码提到BFF,加Toggle做路由
- 拆分独立服务,通过Toggle切流量
- 待功能稳定后,删除旧服务中的代码
步䠫七:数据拆分
- 数据表归类:数据表按上下文划分
- 解除不必要的数据表关联:跨上下文插叙你的SQL
- 物理上拆分:数据库拆分
总结与心得
在面对业务和技术的同时,我们应该如何正确的判定服务的拆分是否合理,这里没有标准答案,需要根据主导者自己的判断进行权衡;差分过程中技术实现难度复杂度大,工作量也不小,除了从技术测解决是否还有其他途径
个人心得:微服务拆分————早识别,早准备,等时机,一鼓作气!