对现有系统做微服务化改造 ######################## 相比从头开始落地服务,对现有系统做微服务化改造,面临更多的挑战:: 1. 应用和数据表紧密耦合在一起,代码模块和表是多对多的依赖关系 一个模块会访问多张表,多个模块也会对同一张表进行访问 而且由于表都在一个数据库里,开发人员往往会随意对表做关联,有时候甚至 Join 5~6 张表以上 这样,代码模块和表之间的关系是剪不断,理还乱 我们很难清晰地划分代码和数据表的边界,也就很难把它们封装成独立的微服务 2. 如何保证系统的平滑过渡 系统现在已经在运行了,我们的改造不能影响业务的稳定性 微服务落地后,现有的系统要怎么对接微服务,数据要怎么迁移 应对这些挑战:: 1. 要保证比较合理的服务设计,才能达到优化系统架构的目的 2. 要做到整个过程对现有系统的影响比较小,才能达到系统改造顺利落地的目的 单体系统的维护带来了一系列的问题:: 1. 从应用方面来说,各个系统功能重复建设 比如:很多系统都会直接访问库存相关的表,类似的库存逻辑散布在很多地方 另外,如果修改了库存表的某个字段,这些系统同时会受影响,正所谓牵一发而动全身 2. 从数据库方面来说,数据库的可用性是比较差的 如果某个系统有慢查询,它就很可能拖垮整个产品数据库,导致它不可用 还有,这么多系统同时访问产品库,数据库的连接数也经常不够用 微服务改造过程 ============== 选择要改造的服务:: 这里涉及了多个微服务,如果同时进行服务化改造的话,牵扯太大,很难落地。 于是,我们选择从库存微服务开始: 1. 库存的业务很重要,库存的规则也比较复杂,如果我们能够对库存逻辑进行优化,这会带来明显的业务价值 2. 电商的库存概念相对独立,涉及的表也比较少,我们可以相对容易地把它从现有体系中剥离出来 整个改造过程,一共分为两个阶段:: 1. 准备阶段 这个阶段为微服务改造做好前期的准备工作,具体步骤包括了: a. 圈表 b. 收集 SQL c. SQL 拆分 2. 实施阶段 这个阶段实际落地微服务,具体步骤包括: a. 微服务开发 b. 服务接入 c. 数据库独立 .. image:: https://img.zhaoweiguo.com/knowledge/images/architectures/evolutions/be-microservice1.jpeg 准备阶段 ======== 1. 圈表 -------- 圈表就是用来确定库存微服务具体包含哪些表,也就是确定服务的数据模型:: 在确定了表以后,库存微服务就负责这些表的访问: 1. 库存微服务也不会访问其它的表 2. 而业务系统后续将通过库存微服务的接口,实现对这些表的访问 圈表是微服务改造中比较有挑战性的地方:: 它实际上对应了服务的边界划分 只是针对老系统做服务化改造的时候,更多的是从数据库表的角度来考虑划分,这样更好落地 要求:: 1. 要满足所有的库存访问需求,这些表之间关系紧密,和其它的表关联不大 2. 这些表的数量不能太多,一般不超过十几张 这样,我们既容易拆分数据库,又能控制服务的粒度,保证功能聚焦 .. important:: 在微服务改造中,确定哪些表属于这个服务,会直接影响后续的所有改造工作,这需要有经验的业务架构师和数据架构师参与进来,通过深入地分析现有的业务场景和表的关系,才能对库表进行合理的划分。 对现有系统的改造,服务的边界划分主要是从圈表入手的,而不是从一个服务应该有哪些功能入手的,这一点和新服务设计是有所不同的。这有两方面原因:: 1. 如果确定了服务包含哪些表,也就大致确定了服务有哪些功能 而表是现成的,它比业务功能要直观很多,所以从表入手比较高效 2. 如果从表入手,构造的服务和表是对应的,服务包含的是完整的表 不会产生一个表的一部分字段属于库存服务,而另一部分字段属于别的服务的情况 避免表字段的拆分带来额外的复杂性 .. note:: 因为这是对现有系统的改造,为了避免一下子引入太多变化,我们先不对库存的表结构进行调整,表结构的优化可以放在服务的升级版里做,这样对业务系统的影响也最小 2. 收集 SQL ----------- 在确定了哪些表属于库存服务后,我们会收集所有业务系统访问这些表的 SQL 语句:: 包括它的业务场景说明、访问频率等等。 库存微服务后续就针对这些 SQL 进行封装,提供相应的接口给业务系统使用。 这里,服务开发团队负责提供 SQL 收集的 Excel 模板,各业务系统开发团队负责收集具体的 SQL。 3. 拆分 SQL ----------- 对于收集过来的 SQL 语句,有些 SQL 不仅仅访问圈定的这几张库存表,还会和产品库中的其他表进行关联。 对于这样的 SQL 语句,我们就要求各个业务团队先进行拆分,保证最后提供给服务开发团队的 SQL,只包含访问库存的相关表。通过 SQL 拆分,我们切断了库存表和其他表的直接联系,等后面微服务落地后,业务系统就可以通过接入微服务,完成现有 SQL 的替换。 SQL 拆分,会涉及一定的业务系统改造,这部分工作主要由各个研发团队负责,一般情况下,性能可能会受些影响,但问题不是很大。 实施阶段 ======== 4. 构建微服务 ------------- 包括:: 接口设计、代码开发、功能测试等步骤 对业务方提供的 SQL 进行梳理,然后对接口做一定的通用化设计, 避免为每个 SQL 定制一个单独的接口,以此保证服务的复用能力 这部分工作由微服务开发团队负责:: 第一版的服务主要是: 1. 做好接口设计 2. 聚焦业务功能 以保证服务能够落地,业务系统能够顺利对接为目标 将来: 服务可以持续迭代,内部做各种技术性优化, 只要服务的接口保持不变,就不会影响业务系统 5. 接入微服务 ------------- 库存服务经过功能和性能验证以后,会由各个业务开发团队逐步接入,替换原来的 SQL 语句。 .. note:: 这部分工作主要由业务研发团队负责,难度不大,但需要耗费比较多的时间。 6. 数据库独立 ------------- .. note:: 当服务接入完成,所有的 SQL 语句都被替换后,业务系统已经不会直接访问这些库存的表。这时,我们就可以把库存相关的表,从原来的产品库中迁移出来,部署成为一个物理上独立的数据库。业务系统是通过服务来访问数据库的,因此,这个数据迁移对于业务系统来说是透明的,业务团队甚至都不用关心这些表的新位置。 通过库存表独立成库,我们可以从物理层面,切断业务团队对这些表的依赖,同时,也可以大幅度降低产品库的压力,特别是大促的时候,库存读写压力是非常大的,数据库独立也为库存服务后续的技术优化打下了基础。 .. note:: 这部分工作主要由微服务开发团队和 DBA 一起配合完成,主要是要避免业务系统还有遗漏的 SQL 语句,避免它们还在直接访问库存的表。我们可以在迁库前,通过代码扫描做好相应的检查工作。 总结 ==== .. figure:: https://img.zhaoweiguo.com/knowledge/images/architectures/evolutions/be-microservice2.jpeg 改造前架构图 .. figure:: https://img.zhaoweiguo.com/knowledge/images/architectures/evolutions/be-microservice3.jpeg 改造后架构图 .. important:: 系统改造不会产生直接的业务价值,对于业务开发团队来说,他们往往还需要承担大量新需求的开发工作。所以,**从项目推进的角度来看,这种核心服务的改造,很多时候都是技术一把手工程。** 在微服务改造过程中,老板要高度重视,大家事先定好时间计划,每周 Review 进度,协调各个团队工作的优先级,确保改造的顺利落地。 .. important:: 基于现有系统进行改造和全新的服务设计是有所不同的,我们不能追求理想化和一步到位,而是要考虑到系统的平滑过渡,先实现微服务的顺利落地,后续再考虑各种优化。 参考 ==== * 【极客】架构实战案例-可复用架构案例(二):如何对现有系统做微服务改造: https://time.geekbang.org/column/article/209597