微服务架构中的服务拆分方案和案例

博主:爱码叔
个人博客站点: icodebook
公众号:爱码叔漫画软件设计(搜:爱码叔)
专注于软件设计与架构、技术管理。擅长用通俗易懂的语言讲解技术。对技术管理工作有自己的一定见解。文章会第一时间首发在个站上,欢迎大家关注访问!   

    在微服务架构中,对于服务范围的定义应该以发展的眼光去看待。随着系统的发展,可能会出现微服务的拆分和合并。这就像面向对象设计的单一职责原则,每个人对单一职责的认知各不相同,而且随着系统的发展,原来符合单一职责的对象可能会变得复杂,直到某一天被重构。微服务也是同样的道理。某个服务中的一块业务,在设计之初可能非常简单,并且依附于其他业务。但是随着业务的发展,该业务逐渐发展壮大,直到和其他业务也能平起平坐,此时需要考虑微服务的拆分。

    我们设想如下场景。在某个微服务中,存在服务A,原来负责业务A和B。最初B的业务比较小,随着企业发展,B业务越来越受到重视,也在不断发展壮大。现在需要从A服务中将B业务拆出,构建新的服务B。以下是此场景的拆分方案。

一、方案简介

    本文的微服务拆分方案旨在提供一种平滑拆分微服务的方法。尽量降低服务拆分的风险,并且能够回滚。本方案在实际项目中有过验证,基本做到了零问题,平稳拆分。

    微服务拆分的内容主要包括两个部分——服务和DB(包括但不限于,也可能有消息队列、Redis、云上存储的拆分)。开发、测试阶段均使用两个独立的DB,但是上线分为以下三个步骤,尽量确保稳妥。

  1. 只拆服务,不拆DB
  2. 拆分DB Schema
  3. 拆分DB

下图省去了拆分Schema的过程。

二、拆分服务

    第一阶段,只拆分服务,不拆分 DB。拆分服务的工作是将原 A 服务的 API 拆一部分出来,移到到新建的 B 服务中。暂时保留两个版本的 API。这个阶段不拆分 DB,目的是为了先确保 API 拆分的正确性、完整性。一旦出现问题,切换路由,快速回滚,不会污染数据。

2.1 拆分服务方案概要

    拆分服务的方案考虑如下要点。

    1)将服务 A 中 B 业务的 API 全部拆分到新的微服务 B 中

    2)A 服务中暂时保留 B 业务 API,以便出问题时,切换回原有 API

    3)日志需要记录统计哪个服务的 API 被调用

    4)B 服务继续使用原有 DB

2.2 涉及到改动的 API 分类

    首先需要确定迁移的 API 范围。可以从 A 服务的 DB 中找到属于 B 服务的表,向上推出所有受影响的 API。将这些 API,分为下面的三类。

    1)B 业务的 API 只访问 B 业务表

    这一类是最简单,只需要将已有 API 从 A 服务原样照搬到 B 服务。原有API直接迁移。

    2)A业务API,但要使用B业务表

    拆分前 ,在A 服务中可以访问到B业务表。拆分后A服务无法直接访问B业务表,只能通过B服务API。因此,需要在B服务中新增此类API

    3)B 业务的 API,但要使用 A 业务表

    原理同上。B服务需要迁移这部分API外,还需要在A服务中新增API,供B服务API调用。

    API的分类和解释如下图所示。

2.3 拆出的 B 服务开发。

    针对以上三类 API,对 B 服务的开发如下。

    1)第一类直接搬到 B 服务中

    2)第二类,B 服务 提供 A 服务需要的 API

    3)第三类,B 服务需要使用 A 服务提供的新的 API 操作数据

2.4 原 A 服务修改

    1)首先,所有受影响的 API 版本需要弃用,但可回滚。通过版本号,以路由控制是一种方案。

    2)第二类,A 服务改为访问B服务 API 获取数据

    3)第三类,A 服务提供新的 API 供B服务调用

2.5 A、B服务之外受影响的服务修改

    站在微服务的视角,将被迁走的A服务中B业务的API(API分类中的1和3),是对其他服务产生影响的原因。这些API决定了其它服务的受影响范围。

    我们需要找到哪些服务受到影响、这些服务中的哪些业务受到影响。

    首先,通过工具、关键字查询等方式,找到所有调用A服务的服务。然后分析使用的 API 是否有属于 B 业务的 API。然后再分析被影响到的具体修改点。

    所有被影响的地方,都需要将原来访问 A 服务的 B 业务 API,改为访问 B 服务。并且需要能够灵活切换,方便回滚。

2.6 统计监控

    提前设计好日志。上线后通过日志统计,确认所有B业务的API全部走B服务,不再走A服务。

三、拆分 DB schema

    经过 API 的拆分和监控。已经确认 API 拆分完整,并且所有 B 业务的 API 调用都走 B 服务。但是有几点没法得到更严谨的验证。

  • 由于 DB 没有拆分,所以不能确认是否 A 服务所有对 B 业务表的访问都被移除,可能存在遗漏。
  • DB 权限的设置,没有在生产环境验证。

    如果直接拆分 DB,一旦出现以上问题,程序会出现错误,数据将被污染,并且恢复难度较大。因此,先在一个 A 的 DB 上建立 B schema,模拟 DB 拆分。

    这个阶段的开发工作如下。

  • 在原 DB 上建立 B 业务的 Schema,将 B 业务表迁移到 B 业务 schema
  • 重新建立 A、B 服务的 DB 账号,重新分配相应权限
  • A、B 服务修改 DB 账号和 schema 信息

    上线时的工作如下。

  • 数据迁移。迁移 B 业务表的数据到B Schema中
  • 切换 A、B 服务 DB 账号

四、拆分DB

    拆分 Schema 后,确认 A Schema 中 B 业务表已经没有数据流入,B schema 数据流入正常,系统运行稳定后,可以进行 DB 的拆分。

    DB拆分分为以下几步

  • 提前建立 B 服务 DB,从 A 服务 DB 同步数据
  • 准备好 B 服务所需要的 DB 账号信息
  • A 服务 DB 数据同步完成后,切换 B 服务到新的 DB

五、收尾

    DB 拆分后,确认 A DB 中的 B schema 没有数据流入后,可以进行收尾工作。主要工作如下。

  • 移除A DB中的 B schema
  • 移除A DB中的 B 业务表
  • 其他服务中如果有临时保留的,用于切换回 A 服务原来 API 的代码,进行删除。
  • 移除A服务中老版本的API

六、其他受影响方

    DB 信息的变更,会影响到从 A DB 取数的第三方,包括但不限于 报表、大数据、数据集成方。需要提前沟通,告知 DB 改变的信息和时间。

七、总结

    本方案原来分两个阶段走,先拆分服务、再拆分DB。在实施过程中,团队决定增加拆分schema的阶段,以此降低直接拆分DB带来的风险。实际项目中比文中描述更为复杂,还会涉及路由修改、消息队列拆分等工作。

从宏观看待类似微服务拆分工作。我总结以下几点

  • 分析先行,合理的分析方法,准确确定影响范围
  • 分多阶段进行,一次拆分一部分,风险可控、方便回滚
  • 新的新建;旧的保留;新的验证;旧的删除
  • 每一个阶段都要有风险应对方案
  • 每一个阶段都要有验证方案
  • 不要忽视对第三方的影响
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值