因为公司业务还是应用的paoding rose + jade + resin的技术架构,导致新员工学习老本高,且框架自身曾经很多年没人保护了,所以决定迁徙至springboot2 + mybatis + tomcat.

前言

以下是我的迁徙实际,任何开发个别都是分为三步:写代码、测试、监控。

很多程序员,并不关注测试和监控,这就是俗称的“管杀不论埋”,写完代码就认为完结了,默认程序曾经好使了,问题全靠接口调用方反馈或者上线后再排查,一方面会影响集体的名誉,他人会感觉你不靠谱;另一方面容易给公司造成严重损失。

对于框架迁徙,重构类的工作来说,测试和监控尤其重要,因为所有的接口,都有可能出问题。

筹备工作

1) 调研springboot框架与paoding-rose框架的不同语法,尽可能找出代码中paoding-rose的非凡规定,列表进行比照。如paoding-rose的json数据须要加一个"@"符号,@Get,@Post这样的非凡标签,以及ControllerInterceptorAdapter这样的Intercepter等等。paoding-rose是基于spring的,底层实现是一样的,然而为了易用做了一层本人的包装和适配,对于一些我的项目中一些非凡用法,高度重视。

2) 调研mybatis和jade框架的异同。之前公司的jade框架是通过zookeeper获取配置,jade提供主从拆散,分表查问等性能,然而mybatis原生并不反对;jade是基于注解sql的,mybatis要改成xml配置的模式。

3) 部署相干的异同。从resin到spring内置的tomcat,相干部署配置是否能够替换,如何适配公司的部署零碎。

分阶段迁徙

参考其余我的项目的迁徙教训,决定分两阶段迁徙,不便定位问题,确认影响。

第一阶段:迁徙dao层,jade迁徙到mybatis

第二阶段:paoding rose + resin迁徙到springboot2 + 内置tomcat
次要为controller层及相干配置文件等。

迁徙dao层

这一阶段遇到的问题次要是sql文件改写和主从拆散。

1) sql文件改写

sql文件改写次要是体力活,怎么在改写70多张表的sql状况下还不出错,真的很难。

后期打算应用通用mapper这个框架来做,这样能够生成局部罕用办法。然而起初深刻理解后发现,业务sql都比较复杂,根本默认的sql不能用,而且应用通用mapper必须从新生成model文件,这样的话所有原来的model文件都须要更改,controller,service里的业务逻辑都得批改。应用通用mapper批改了几张表后,发现费时费力,而且对代码改变太大,危险太大。

因而放弃应用通用mapper,改为手写mybatis相干文件,之前曾经主动生成了一堆mapper文件,外面的model字段名和数据库表字段名的映射map还是能够应用的,不便不少。

我是采纳边改写,边自测的形式来做的,在test目录下写比照测试,比照新旧框架在雷同申请参数下的返回值异样(select语句)。重复性劳动很容易大意/疲劳导致出错,比照测试帮忙我测出了很多问题。

2) mybatis实现主从拆散

这里咱们采纳的是AbstractRoutingDataSource + mybatis插件的模式,通过mybatis插件,拦挡Executor的query办法和update办法,对所有的select语句,通过ThreadLocal变量的模式,指定走从库的DataSource。

迁徙整体框架

迁徙整体框架次要分为几局部:

  1. Controller层的迁徙,次要是注解和返回值。
    对于注解,一位共事写了一个python脚本,将两个框架的对应注解进行了自动化改写,极大晋升了工作效率。
  2. 一些paoding rose的非凡应用。比方返回值@符号,代码外面一些其余用到老框架的中央。

返回值@前缀这个,让我粗浅感触到了整洁代码的重要性。因为我的项目代码很老经手了很多人,到处都是@符号,代码搜寻又不好匹配。在paoding rose框架外面,@符号是标识json构造返回的,返回数据会去掉它,然而springboot并不会,这种问题没有报错日志,一旦带到线上会导致客户端无奈解析返回后果,问题十分重大。

先改了能找到的用老框架的中央,而后去掉maven依赖,找不到包的天然会报错,一个一个改。

  1. 启动相干的配置

因为线上存在同一台机器部署多个节点服务的状况,因而服务端口、log配置文件必须是可配置的。这里我的实现是,log4j2.xml文件放在打的fat jar雷同目录下。
我的项目中resource目录放一个application.yml文件,fat jar同级目录配置一个application.properties, 蕴含以下三个值的配置

server.port=<%= scope["config::http_port"] %>server.tomcat.accesslog.directory=<%= scope["config::prog_logdir"] %>logging.config=<%= scope["config::basedir"] %>/log4j2.xml

读取配置文件时,application.properties中的配置优先级更高,这样确保服务启动的端口、access日志目录和其余日志目录都是可配置化的。

代码改写之后,就是沉重的测试工作了。

首先还是比照测试,对所有重要接口都做了新老框架下接口的比照测试,黑盒比照,间接申请http申请比照返回值,申请参数尽可能抓包用实在数据。有些接口有非凡的行为逻辑,或者外面有一些动静参数,每次申请都不一样,这种就须要灵活处理了。总共比照了80个左右的接口(日申请量top80的接口)。

而后在测试机器上部署,应用客户端抓包看返回值是否有异样,同时察看服务器谬误日志。(这里顺便提一句:error级别日志放到独自的文件里,这样查谬误日志会十分不便)。因为是很老的我的项目,客户端通过了很多个版本迭代,最新版客户端可能曾经不必这些代码了,肯定是测不全的。

上线

在测试环境测试没有新问题产生,这种状况下就能够开始着手上线了。

迁徙dao层时, 分为两个阶段,第一阶段上线了多数几张表,确认mybatis相干配置没有问题,之后又对所有表的替换做了上线。

线上共有60多个节点,先上线一个节点,察看谬误日志,几个小时后没有什么sql相干异样抛出,再上线其余机器。

上线之后肯定要及时察看各种报警和谬误日志。

这里顺便提一下线上监控及日志的一些实际。

当火线上次要分两局部:

机器和nginx

运维同学建设了机器指标监控看板和阈值报警,以及基于nginx日志的http申请的pivot统计。

比拟重要的机器指标包含:

  • cpu负载
  • 内存残余量
  • /home分区磁盘残余
  • 跟分区磁盘残余
  • 入网流量
  • 出王流量

比拟重要的域名服务指标包含:
域名下http接口申请4xx,5xx的数量及占比

服务端业务

业务由服务端同学负责,次要分两局部:
第一局部是metric监控及基于监控的报警。

第二局部是接入了公司的elk和druid数据。将业务日志,如接口申请日志,服务异样日志等打入elk中,能够不便的定位和查问问题。另外,服务端同学还基于elk日志做了Exception的报警机制,当某类型的Exception超过正常值,会触发短信邮件报警。

欠缺的监控和报警体系是重构的牢靠保障,本次重构没有太大的线上问题,然而上线后靠监控和报警,发现了不少小问题,及时进行了修改。

总结

总体来说,这次重构比较顺利。

一方面得益于后期的充分准备和其余模块的局部教训,另一方面得益于比照测试和线上监控报警体系。

重构一个3000万日活,每天17亿申请,峰值qps32k的服务,肯定要小心小心再小心。要确保不出问题,肯定要做好比照测试和线上报警。

我的比照测试次要是dao层和接口级别的线下、线上比照测试,如果可能在线上空跑一段时间用实在流量做比照是最好的(老本比拟高,且须要运维同学反对)。

本文由博客一文多发平台 OpenWrite 公布!