关于后端:服务端框架重构心路历程

30次阅读

共计 3285 个字符,预计需要花费 9 分钟才能阅读完成。

因为公司业务还是应用的 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 公布!

正文完
 0