分解单块系统
小的,增量修改是贯穿整个微服务改造的核心要点,能够清楚会带来什么影响,能够更好的错误的代码,理解如何降低这些错误所造成的影响。从最开始就要养成及时寻找接缝的好习惯,从而减少分割服务的代价,这样才能够在未来遇到新需求时继续演化我们的系统
从接缝处可以抽取出相对独立的一部分代码,对这部分代码进行修改不会影响系统的其他部分。识别出接缝不仅仅能够清理代码库,更重要的是这些被识别出的接缝可以成为服务的边界
要将单体系统做分离,要考虑接缝是否找到了,应该先将哪个拉出来。最好考虑一下把哪部分代码抽取出来得到的效益最大,而不是为了抽取而抽取
- 改变的速度:对于需要进行大量修改的单元,将其抽离出来单独开发速度大大加快
- 团队结构
- 安全
- 技术
另外抽离单元出来还要考虑这部分代码与其他组件的依赖有多乱😹,一般数据库是杂乱依赖的源头
将横跨多个限界上下文的表之间的耦合切断,是一个复杂的问题
1、打破外键依赖 2、共享静态数据:使用静态配置文件或者构建单独的服务(如果很小那就没有必要) 3、共享的可变数据是个大麻烦,对于共享的这部分需要添加一个中间包作为将数据库层的抽象建模层具象化 4、将共享的数据表进行拆分
实施分离时先分离数据库(也是从易于修改和回退的部分做起)
将数据拆分后会遇到的问题就是事务问题,可以将操作加入到队列中通过重试来保证所有的操作都成功执行,保证最终一致性。或者为每一个操作注册补偿事务,当出现失败就进行事务回退,一般这种方案需要额外的事务管理器来管理(例如dtm)
两阶段提交:分为投票和执行阶段,只有所有的组件都告诉事务管理器可以继续执行才会执行这个事务
无论哪种方案都会增加复杂度,如果涉及到分布式事务的,一定要尽量避免将他们放在不同的地方。
通过接口来共享数据,并且为服务增加一些缓存来加快数据获取的速度。对于大数据的接口,为了避免服务端不必要的等待,发起调用的系统可以构造好请求后发给服务端,服务端相应202表示请求已经接收了还在处理,客户端就不断轮询直到201状态,表示请求处理完成了,然后发起调用的系统就可以获取这个数据了。
部署
专注于保持服务能够独立与其他服务进行部署的能力,倾向于一个服务一个代码库,并且都配有自己的CI,基于镜像构建服务,并让整个流程自动化
没有对代码进行验证的CI不是整整的CI
当持续集成遇上微服务是,需要考虑如何把CI的构建和每个微服务映射起来。
一个CI、一个代码库、多个服务: 如果只修改了某个服务的代码,也会造成整个服务的重新部署
每个服务有独自的CI以及代码库、独立的测试是更好的实践
构建流水线,使得部署过程中某步执行出错能够快速知道而不需要等到所有的都执行完
定制化镜像,为每个服务预装基础服务,例如日志、监控工具