122

如何把复杂单体应用快速迁移到微服务

 5 years ago
source link: http://www.10tiao.com/html/164/201806/2652898760/1.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

 作者:彭展旋,来自金蝶随手记的后端开发工程师,目前做项目管理相关工作,逐渐转型架构,在服务化、分布式事务、p2p金融系统设计、互联网资讯系统等领域有相关经验。


从我接手过的一个项目说起。先上一个无关紧要的图提提神:


随着项目快速迭代,项目代码变得臃肿,数据表已经接近一百张了。其中部分模块代码消耗cpu和内存大,十几个开发人员在同一个工程里面同时开发着十来个特性,系统如下问题凸显:


1、特性耦合,发版困难

往往一个特性的改动,会牵涉到若干模块,多个特性代码改动重叠,给测试以及合板,发版带来了极大的考虑,降低了发版的效率。


2、非弹性部署,扩展能力差

有些模块需要消耗大量cpu和内存,有些模块需要支持高并发,有些模块需要很少的服务器资源,由于都在单一的系统中,各个模块之间公用同一套服务器资源,分配不均衡,不能针对具体业务进行合理配置扩展。


3、系统业务复杂,接手项目困难

在单一的系统中,涵盖了众多的业务,一个新入职的同事,花三个月可能都未必能熟悉所有的模块,模块间的各种耦合更是让人伤神;不敢轻易调整代码,修改一个问题极易引发另外一个问题。


4、技术升级困难

由于在同一个项目中,技术架构单一,引入一个新技术对所有模块均会有所影响,调整难度极大,增加技术升级风险,整体技术成保守状态,难以升级以适应快速发展的互联网技术。


为此,服务化拆分提上了日程,喵~


服务化拆分流程

在摸透系统里面所有的业务和数据库的前提下,我们才可以进行服务化的拆分。由于该系统在线上运营时间较久,在参与系统迁移的同事继续迭代了若干需求和线上问题跟进之后,对整个系统的业务都了解的前提下展开服务化拆迁工作。


先梳理各个模块的数据模型,然后确定每个模块的职责,从而可以梳理清晰各个服务的边界。


1、解耦老系统外部关联

实际的业务场景和系统交互异常复杂,在这里我简化成以下模型进行说明:

根据确定下来的服务的职责和边界,创建新服务程序和数据库,在新服务中约定B、C接口,把老系统中对外依赖A全部转接到新系统,新系统通过编写的路由器,把请求路由到老系统。

之所以把外部系统关联解耦放在第一位,是因为外部系统对接需要协调对应的项目组配合整改,周期不可控,需要先把这部分不可控的先完成上线,方便后续系统内部模块快速拆解上线。


2、解耦老系统模块间关联

把老系统模块间直接调用A,提升到rpc或者http调用B,对外暴露接口,打断原有模块间业务层或者数据层的直接调用;

原有系统数据库sql关联查询需要按照模块进行拆解,避免跨模块表关联操作;


3、程序迁移到新系统

按照模块,把相关程序迁移到新系统。


在做解耦老系统模块间关联和程序迁移的时候,需要对老系统业务有深刻的掌握,清晰数据库所有表和字段的作用,以便能快速迁移。


4、老系统数据全量迁移

把老系统中的所有数据,通过脚本直接迁移到对应新的数据库中。至此,所有业务数据的写入和读取都是基于新服务的数据库了,从把老系统迁移到了新系统。


关于服务化拆迁的灰度上线

根据系统的业务,制定对应的灰度上线策略。由于我们系统整个业务是围绕着产品来开展业务的。所以可以在灰度发布(金丝雀部署①)的时候,发布灰度测试产品,将白名单用户流量打到新版本的服务器分组上面进行验证。待验证没有问题之后,再逐步开放给全量用户。


在验证期间,旧版本如果需要继续流入业务数据,所产生的新的和改动的业务数据需要再次增量迁移到新数据库中。这样会增加增量数据迁移的工作量,容易出错。我们在升级的过程中停止了老版本系统业务数据入库:


其中灰度测试用户产生的数据只存在于新数据库中。


如何给快速迭代的系统进行拆分

一般互联网企业版本迭代速度都比较快,所以系统迁移的速度一定要迅速。如果周期太长,一个大的需求下来,系统改的面目全非系统迁移的相关工作就得重头再来了。


为了能尽快推进系统拆分,总结以上流程,我们要考虑如下五个步骤:

  1. 需要外部项目组配合的事情先处理完:创建新服务,进行依赖迁移(迁移外部系统接口依赖,迁移外部消息依赖);

  2. 接口系统内模块间依赖,定义好服务的职责和边界;

  3. 快速迁移模块到新服务,同时进行数据迁移,进入灰度测试环境;

  4. 灰度测试验证完毕,迁移增量数据到新数据库,全量用户迁移至新系统;

  5. 线上稳定后,下线老系统,回收相关运维资源。


迁移之后要继续完善的事情

  1. 跟上服务化技术配套:服务拆分之后,系统的运维需要辅助额外的代价,维护和测试难度几何级别增加,我们必须要对应的配套技术:自动化测试,持续集成,自动化部署,配置中心,任务中心,日志监控等;

  2. 分布式一致性事务问题:为了解决此类问题,我们可以通过业务补偿、可靠事件模型,TCC模式进行开发。


系统迁移工作中带来后续工作的启发

  1. 即使是没有做服务化拆分,系统间各个模块也要职责边界定义清晰,梳理清晰业务模型,保证模块间的低耦合,以及模块的高内聚;

  2. 尽量避免过多的数据表关联查询,把数据库当成存储数据的介质,业务逻辑转移到程序中实现,这也为后续分库分表,服务化拆分做好了准备;

  3. 提前准备服务化配套技术,重视底层平台大家。强大的底层平台支撑,帮助我们填平前人已经踩过的坑:灰度发布,服务升级回退,服务注册发现,熔断降级,自动化部署等;

  4. 服务化之后,新技术尽量从边缘业务进行尝试,积累相关的迁移,服务化,运维问题,构建了一套相对完善的方案,行程一整套技术规范之后,再推广至核心业务中,方便了新技术的布道;


附录:

① 金丝雀发布:https://www.v2ex.com/t/344341

如何实现灰度发布:https://mp.weixin.qq.com/s?src=11&timestamp=1528615037&ver=928&signature=bPiBMM-FLNAqT4AY3lHouaIpQfEbQHhBIPGMaRu-SLWGX37SjyRdgZsJM5PgHPZsULfEDr*Rl9clTrGVF8tYKz4bZJCA-k-r5*DhDO4Bd-ueXdmuo0*nkz1MaMX7XZp9&new=1

产品角度看待恢复发布:https://mp.weixin.qq.com/s?src=11&timestamp=1528615037&ver=928&signature=TtupdOFeY0ob09qrmdu3OQePeGw4qqQBkk-POiyvMs05sqwGlUb8od1IAV14NKqMZn3BVyfbPs-pTvoOiAvxusWWrDSoJl3BYWTM6yg1tj3NngRFLMqCbWGiFysTERLo&new=1

=======作者公众号========


=======广告========

亿级流量网站架构核心技术——跟开涛学搭建高可用高并发系统

作者:张开涛 著

当当 广告
购买


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK