写在前面

想想为什么要做重构?

如果没有能说出来的理由,建议不要轻易重构。

机票系统A的现状

A系统的背景

业务上:从杭州挪到北京,作为重新孵化项目,想要做大做强。行业竞争压力非常大,做不出成绩,项目就会被毙。

技术上:遗留的老系统,在一个其他系统基础上改出来的单体,换手了四次团队,找不到一个了解这个系统的人了。

关系上:北京公司新成立,拿到这个项目,是作为一个大项目来做,也是要树立起标杆的项目。

当时我写的一封邮件,描述的这个系统现状。

国内机票旧系统开发于2006年,期间几十名开发人员在代码里留下了痕迹。不久前移 交到北京新业务研发团队维护,主要问题有: 1、代码量大(40万行),质量不高,结构复杂,难以修改和维护。一些代码的具体作用 和逻辑细节,没有人清楚。很多注释和代码不一致,文档缺乏,比较混乱。 2、业务处理过程逻辑复杂,中间数据冗余,与外部接口耦合度高,性能较差,稳定性 不高,扛不住大促活动压力。 3、对业务过程的数据和状态监控不足,难以管理控制和跟踪,各方使用不方便。 4、刚交接过来,没有人真正懂这个系统的业务,业务方也是空降,这个问题尤其严重

重构面临的压力和选择

当时看来,重做是最好的办法,但是不现实。

业务方:不能停止业务,否则死路一条

开发方:没有太多资源,且半年后大促。

只能选择在老系统基础上重构。

如何推动重构A系统

一个很常见的冲突点在于:

业务方觉得系统重构不带来业务价值,说不定还搞出点bug,是有风险的。

你一说其他的,他们就会说“反正还能用”。

对于重构各方都有自己的观点和要求。
对于业务方来说,要求如下:

  • 业务不停
  • 保障稳定
  • 提升性能
  • 快速开发

对于产品方:

  • 提升用户体验
  • 改版引流
  • 其他同业务方

对于开发方:

  • 资源得到倾斜
  • 最大满足业务和产品需求,同时能够发展研发团队

最终各方达成一致,但是研发肯定是压力最大的。不用怕,在这种临危受命的同时,可以提要求,定规则。(如果初期不把这些要求提出来,中期再提就没那么容易满足了。)

本着这个目标,提出了如下要求:

  • 所有其他项目为这个项目让路,最高优先级
  • 资源主要用来保障这个项目,所有人配合,包括后面招聘的
  • 人员管理等方面,特事特办,所有人不管考勤等制度

怎么定重构目标

平衡短期利益和长期利益

1. 分阶段

先重构搜索模块,然后是订单交易、产品库存。

搜索模块的目标主要有五个:

  1. 培养机票新人。梳理清楚国内机票搜索部分的业务和各种潜规则,培养懂机票的新 人。
  2. 提高代码质量。设计更合理,结构更清晰更易维护,系统耦合更低、扩展性更高。
  3. 提升搜索性能。使系统更稳定,更高效,搜索更快,资源消耗更低,大促不宕机。
  4. 监控搜索过程。统一管理搜索过程中的各种开关和参数调整,管理缓存,跟踪搜索 步骤。
  5. 国内机票搜索去oracle化。 在搜索重构的过程中,用mysql代替旧系统的oracle数 据库。

目标的具体说明:

  1. 培养新人问题,主要是XX\XX\XXX\XXXX。在此过程中,熟悉淘宝技术体系和开发 过程,掌握国内机票业务,能逐步的cover机票系统。

  2. 代码质量问题,主要是项目结构合理的分层,搜索的分段式处理,code review,高覆盖率的单元测试,使项目易懂易上手易维护。

  3. 提升性能方面,主要从简化中间结果和数据结构,理清业务简化旧逻辑,整理各步 骤缓存最大化合理利用缓存结果三个方向来提升系统在CPU计算和内存、以及网络 IO等方面的开销。提高系统吞吐量、QPS,降低响应时间。

  4. 监控搜索过程,通过哈勃、timetunnel+ateye、memlog、系统log等手段埋点,管 理系统多种粒度的开关和参数设置,跟踪和调试搜索流程中的数据和状态、各种外 部接口数据和缓存。

  5. 去Oracle,改用mysql+tddl,实现分库分表,为进一步的分布式架构打下基础。

2. 变组织

  1. 架构师主力,长期大办公室开发,负责核心和全流程
  2. 其他后备力量,负责业务模块+迭代周期
  3. 开发期间,试行996(算加班调休),抢在年底大促前完成重构

重构的过程

第一步:规划

确定规划,分步改造。

启动项目,拉齐思想。

  • 上线启动10/11
  • 灰度发布10/20
  • 功能发布10/27
  • 全部提测11/08
  • 所有上线11/29
  • 机票大促12/21

第二步:明确业务

  1. 重建业务需求稳定,需求是一切的起始点。

第三步:架构调整

分层改造和逐步对接。

所谓分层改造:就是当时我们的系统分为contrller-> ao -> service -> dao -> db

我们可以改造dao层和db层,将oracle换成mysql,service原有的不动,新创建一个实现类,接新的dao层。这样老的和新的实现都有,可以随时切换。

在一个需求周期内,完成业务需求的同时,搭车发布技术改造。

3.1 性能优化

  • 从优化业务处理角度。同步大事务到小事务,异步处理
  • 从优化系统代码角度。多层for循环的优化
  • 从优化数据结构角度。优化掉一个笛卡尔积
  • 从优化缓存策略角度,从静态的缓存时间到动态计算缓存时间。

3.2 引入标准

借鉴之前的ESB经验,解决对接的复杂性问题,标准化集成方式。

不同航司的接口,差异非常大,数据结构也不同,数据的有效性也不同。

原有的外部对接与业务系统耦合严重,对接方式也是五花八门。抽离出一个标准规范,做一套ACS系统来专门对接外部航司的接口。支持更好的横向扩展和维护性。

3.3 灰度发布

通过灰度发布+特性开关,保障可靠上线。

先是预发环境上线,办公室内访问。然后线上灰度,公司内部IP访问。再接着杭州和北京访问。最后全国访问,完全放开。

3.4 监控运维

实现一套全方位的运维系统,快速发现和处理问题。实现线上开关和debug的机制,快速定位问题。对每天的业务数据进行自动统计和发邮件,做到所有人对业务情况了然于心。

最后的效果:

  • 业务上,支持了大量新功能,包括营销促销系统
  • 技术上,重构了新系统,完成了去O和分库分表,保证了大促
  • 产品上,优化用户体验,补齐系统的功能短板
  • 团队上,培养了一批懂业务,懂新系统底层的核心研发人员。

新系统文档完善,架构先进,代码只有旧系统1/3不到,性能提升30倍。

(注:以上案例是秦金卫老师的真实重构案例)

版权声明:本文为javammc原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/javammc/p/15261446.html