200张表+单表记录过亿,10年核心老系统重构之旅

张雄 2022-12-16 13:15:29
作者介绍

张雄,14年IT研发及管理经验,目前担任兰亭集势高级研发专家。

 

一、什么时候需要重构老系统

 

老系统重构,让大家又喜又悲,喜的是程序员,悲的是业务。

 

程序员为啥“喜”:多年前的老技术,以及各种历史原因导致的遗留代码、不需要的业务代码混杂在一起,维护起来,那个酸爽,我相信老司机都懂的。

 

业务为啥“悲”:业务会觉得一堆技术人重心都去发明新轮子,新需求迭代必然受挫。

 

那什么时候可以进行重构?本着技术需要领先业务“一小步”,综合成本和收益、boss意愿、业务的淡旺季、团队对新框架的掌握熟练度等因素,考虑清楚,方可计划和实施。

 

为了追赶业务的发展,笔者有幸成功主导过公司几个历史大系统的重构,接下来将讲述一个核心系统的重构之旅。

 

二、被重构系统的现状

 

此次重构的系统是10多年前的老系统,简单描述,有如下特征:

 

  • 单体应用,200多张表,千万级别记录的表上百个,部分表记录已上亿;

 

  • 要的和不要的业务功能都参杂其中,毕竟那个时候互联网群雄逐鹿,讲究天下功夫,唯快不破,没有严格实施“童子军规”,着实理解;

 

  • 作为核心系统,外部系统千丝万缕,给人麻麻的感觉。

 

三、期望达到的目标

 

  • 不影响业务的正常使用

 

  • 不影响其他系统的正常调用和运行

 

  • 技术架构从单体架构升级到微服务架构

 

因为微服务需要拆分数据库,即从一个大数据库里面,将本系统的表拆到新库,而且此次涉及跨机房(运维哥哥要求的)。

 

所以,技术上涉及数据迁移并升级,以及系统架构和代码升级两部分。

 

四、如何去重构

 

为了达到目标,我的方法如下:

 

 
1、不影响业务的正常使用

 

即使用新架构,全新开发一个系统,数据库也使用新的(即将数据迁移并表结构升级),老系统和老数据库正常运行,等新系统开发部署好,再直接通过运维切换到新域名即可。

 

 
2、不影响其他系统的正常调用

 

老系统之间交互方式梳理清楚,有两种方式:

 

  • 老接口不变,新系统继续兼容老系统的接口调用,比如是HTTP,Hession,RMI等;

 

  • 其他系统和本系统交互的部分,他们也愿意一起升级,就使用新接口方式,那是最好的,具体看场景。

 

 
3、技术架构从单体架构升级到微服务架构

 

1)数据迁移并升级

 

由于跨机房,源数据库数据量比较大(几百G),并且新库我们做了部分表结构调整,在保证老数据库不停机的情况下,我们使用了zookeeper+kafka+canal+otter等组件集群方式搭建,分两个阶段完成数据迁移,即存量数据和增量数据两阶段处理。

 

具体操作的流程图如下:

 

图片

 

  • 通过dump表打包,节约网络带宽,同时记录dump的位点A,方便后续作为增量的起始点;

 

  • 中间备份库作为一个临时库,和新数据库在同一个服务器,这样DBA在临时库改造大表,不影响业务,改造好了,可以直接剪切到新数据库;如果涉及表拆分和复杂业务逻辑,就需要程序来做存量同步;

 

  • 在存量都搞定后,再做老数据库从位点A到新数据库的同步,无业务逻辑,并且可以直接字段对应进行数据同步,使用otter解决,而有业务逻辑等,则使用canal解析bonlog,将数据存到kafka,再通过程序来消费kafka数据,将处理后的数据写入新数据库;

 

  • 待新老数据库数据保持一致后,上线新应用系统,通过配置中心切数据库,并确保切数据后,数据表无“双写”存在。

 

值得提醒的是:

 

  • 一般建议重构时,没有绝对把握,尽量不做表结构修改,因为这样需要搭建对系统本身的运转和业务的理解足够深入,至少各个字段的生命周期;

 

  • 需要充分做好源字段和目标字段的仔细梳理和测试,这里有巨大的工作量;

 

  • 有些表数据会有依赖,所以需要注意同步时表的先后顺序;

 

  • 不要低估在大表上加新索引的时间(当然,如果能够提前做数据归档那是最好的)。

 

2)系统架构和代码升级

 

微服务我们按照业务功能竖切,以及通用非业务功能的横切,建议初期不要切太细,掌握一个度。

 

由于我们使用Spring Cloud这一套,网上相关资料都比较齐全,我就不详述了。

 

在这里,需要重点给大家分享做好系统功能分析,可以按内部和外部两个维度分析:

 

① 内部分析

 

  • 内部功能的代码分析

 

  • 梳理出在使用的表清单和业务逻辑

 

  • 内部Job,含job调度中心和线上服务器各个用户下的cron job等

 

  • 中间件的使用:MQ,Redis等

 

  • 调用第三方的内容:外部翻译接口,支付接口等

 

② 外部调用分析

 

  • 日志分析:access log等追踪访问的IP,追溯对应调用方

 

  • 老数据库表访问来源分析:数据库上加日志分析JDBC直连

 

  • 其他系统对调用API接口的追踪和梳理等

 

五、感想

 

重构老系统,犹如在高速公路上开车换胎:

 

图片

 

所以,为了安全起见,建议大家做好以下内容:

 

  • 事先尽量想明白重构的边界,是部分独立功能重构,还是整个系统重构;

 

  • 并提前给业务打好预防针,争取上级领导们的大力支持;

 

  • 并团队自身做好充分准备工作,分析工作,以及其他软技能,比如上下游系统沟通和协调等工作,都尽量做细,正如《孙子兵法》说:知己知彼,百战不殆。

 

总之,重构开始很兴奋,但走到后面满路荆棘,所以,建议大家必须要有突破黑暗,走向光明的“决心”。佛曰:我不入地狱,谁入地狱?!

 

作者丨张雄
来源丨公众号:技术琐话(ID:TheoryPractice)
dbaplus社群欢迎广大技术人员投稿,投稿邮箱:editor@dbaplus.cn
最新评论
访客 2023年08月20日

230721

访客 2023年08月16日

1、导入Mongo Monitor监控工具表结构(mongo_monitor…

访客 2023年08月04日

上面提到: 在问题描述的架构图中我们可以看到,Click…

访客 2023年07月19日

PMM不香吗?

访客 2023年06月20日

如今看都很棒

活动预告