业务重构实践总结

业务重构似乎是必然且合理的过程。一个项目刚开始为了快速上线和试错,总会或多或少出现不合理的地方。当项目活下来了,为了寻求下一步的发展,服务的稳定和扩展性提升了优先级,自然就需要有人来重构了,这也是项目历史遗留的技术债务。

项目背景

  • 公司原有的业务几乎都是PHP编写的,并且处于一个很大的项目里维护和运行,可以说是大杂烩。随着业务发展和用户量的提升,渐渐得暴露了很多问题:
    1. PHP运行效率较低,业务未进行隔离,出问题时相互影响;
    2. PHP 过于灵活的语言特性,导致后期较高的后期维护成本;
    3. 基础框架和服务对PHP支持不足;
    4. 实现灾备比较困难。

重构语言选择

  • 我们选择Java作为开发语言进行重构
    1. 静态类型,多人协作开发和维护更加安全可靠;
    2. 内部基础组件的 Java 版生态比较完善;
    3. 学习成本低,且开发效率较 PHP 没有明显降低。

重构的工作是什么?

  1. 最简单直接的主要工作:就是充当PHP到Java语言的翻译,将PHP代码转化成Java代码,并保持逻辑不变,对上层业务是无感知的;
  2. 除此之外,对业务逻辑进行优化和简化,提高后续的可维护性和开发效率;对服务架构进行优化,提升服务的稳定性和可靠性。这是重构的主要意义;
  3. 重构完成之后,制定完善的验证和上线方案。

实施过程

  • Step 1. 用 Java 重构逻辑
    • 对外暴露的协议(HTTP 、RPC 接口定义和返回数据)与之前保持一致(保持协议一致很重要,之后迁移依赖方会更方便)
    • 尽量翻译而不是重构优化(至少第一版重构采取这样的策略)
  • Step 2. 验证新逻辑正确性
    • 当代码重构完成后,在将流量切换到新逻辑之前,我们会先验证新服务的正确性。
    • 考验对业务的熟悉程度和翻译的准确度(代码太久远,最熟悉的可能只有你自己)
    • 单元测试保证
  • Step 3. 灰度放量
    • 当一切验证通过之后,我们会开始按照百分比转发流量。
    • PHP入口对接底层新逻辑(验证逻辑正确性;之所以不直接从流量入口切换,是为了保证稳定性,在出现问题时可以迅速回滚。)
    • 外网代理切到新接口(保持协议一致,无需前端修改,切换彻底)

经验总结

  1. PHP代码太复杂,项目又不容易跑起来怎么办?
    • 默默睁大眼睛翻译还能怎样。。。
    • 如何验证是否翻译正确?
    • 找个在线PHP执行平台把复杂的代码片断跑起来,按照执行结果编写测试用例
  2. PHP代码太狗血太久远,万一翻译到半死发现这段逻辑根本已经没用了怎么办?
    • 把你的服务当nginx用,参数不符合条件的转发到旧服务,记录入参和返回结果,打日志和监控观察流量

最后

  1. 不能相信自己
  2. 不能相信别人
  3. 只能相信自己
  4. 乖乖覆盖测试用例