业务重构似乎是必然且合理的过程。一个项目刚开始为了快速上线和试错,总会或多或少出现不合理的地方。当项目活下来了,为了寻求下一步的发展,服务的稳定和扩展性提升了优先级,自然就需要有人来重构了,这也是项目历史遗留的技术债务。
项目背景
- 公司原有的业务几乎都是PHP编写的,并且处于一个很大的项目里维护和运行,可以说是大杂烩。随着业务发展和用户量的提升,渐渐得暴露了很多问题:
- PHP运行效率较低,业务未进行隔离,出问题时相互影响;
- PHP 过于灵活的语言特性,导致后期较高的后期维护成本;
- 基础框架和服务对PHP支持不足;
- 实现灾备比较困难。
重构语言选择
- 我们选择Java作为开发语言进行重构
- 静态类型,多人协作开发和维护更加安全可靠;
- 内部基础组件的 Java 版生态比较完善;
- 学习成本低,且开发效率较 PHP 没有明显降低。
重构的工作是什么?
- 最简单直接的主要工作:就是充当PHP到Java语言的翻译,将PHP代码转化成Java代码,并保持逻辑不变,对上层业务是无感知的;
- 除此之外,对业务逻辑进行优化和简化,提高后续的可维护性和开发效率;对服务架构进行优化,提升服务的稳定性和可靠性。这是重构的主要意义;
- 重构完成之后,制定完善的验证和上线方案。
实施过程
- Step 1. 用 Java 重构逻辑
- 对外暴露的协议(HTTP 、RPC 接口定义和返回数据)与之前保持一致(保持协议一致很重要,之后迁移依赖方会更方便)
- 尽量翻译而不是重构优化(至少第一版重构采取这样的策略)
- Step 2. 验证新逻辑正确性
- 当代码重构完成后,在将流量切换到新逻辑之前,我们会先验证新服务的正确性。
- 考验对业务的熟悉程度和翻译的准确度(代码太久远,最熟悉的可能只有你自己)
- 单元测试保证
- Step 3. 灰度放量
- 当一切验证通过之后,我们会开始按照百分比转发流量。
- PHP入口对接底层新逻辑(验证逻辑正确性;之所以不直接从流量入口切换,是为了保证稳定性,在出现问题时可以迅速回滚。)
- 外网代理切到新接口(保持协议一致,无需前端修改,切换彻底)
经验总结
- PHP代码太复杂,项目又不容易跑起来怎么办?
- 默默睁大眼睛翻译还能怎样。。。
- 如何验证是否翻译正确?
- 找个在线PHP执行平台把复杂的代码片断跑起来,按照执行结果编写测试用例
- PHP代码太狗血太久远,万一翻译到半死发现这段逻辑根本已经没用了怎么办?
- 把你的服务当nginx用,参数不符合条件的转发到旧服务,记录入参和返回结果,打日志和监控观察流量
最后
- 不能相信自己
- 不能相信别人
- 只能相信自己
- 乖乖覆盖测试用例