1. 背景
最近在学习 tauri
软件开发,看到了一个软件工程名词 Brownfield 模式,感觉还蛮有感触的。
结合自己过往几个 Brownfield 项目经历,简单的做下 Blog 记录~
2. Brownfield Pattern
2.1. 棕地模式概念
棕地模式是指在已有、成熟且通常规模庞大、复杂且可能存在技术债务的软件系统上进行开发、维护和演进的一种软件开发模式
这个术语借用了房地产和城市规划中的“棕地”概念,即指那些曾经被开发过,但现在可能废弃或需要改造的土地。
在软件领域,它特指那些已经投入使用多年,承载着核心业务逻辑,但可能缺乏最新技术、文档不全、代码结构混乱或难以扩展的遗留系统。
2.2. 特点
- 遗留代码和技术:基于一个已有的大型且复杂的代码库,
代码由不同时期、不同团队、不同技术栈编写
演变而来 - 业务连续性和稳定性优先:在飞机飞行中修飞机引擎,部署流程可能老旧、手动,且风险高
- 大量技术债务:架构设计缺陷、文档缺失、代码冗余、缺乏测试(环境)、依赖过时、遗留代码
- 复杂性与耦合度高:技术债务存在、模块之间高度耦合以及研发对系统理解局限,存在高风险与不确定性,导致对 Brownfield 项目修改、新增功能特性引发意想不到的副作用
2.3. 应对策略
- 逆向工程理解:文档缺失,开发人员需要通过阅读代码、调试,
与业务专家、团队老人交流
,重新梳理出系统的现有行为和业务逻辑 - 绞杀者模式:逐步用新的服务或模块替换旧系统中的功能,最终将旧系统“绞杀”掉
- 渐进式重构和改进:推到重来通常不可行或风险过高,需要考虑如何与这些旧技术共存、集成或逐步迁移,棕地模式倾向于小步快跑模式、渐进式改进、局部重构方式来提升系统质量
- 测试调整:遗留系统可能缺乏自动化测试,或者测试覆盖率低 → 建立测试环境改进测试体系是确保安全的重要环节
2.4. Greenfield 或 Brownfield 模式并不总是泾渭分明(对比总结)
特征/模式 | Brownfield (棕地) 开发 | Greenfield (绿地) 开发 |
---|---|---|
起点 | 现有、运行中的系统,包含遗留代码和基础设施。 | 从零开始,没有现有代码或基础设施。 |
技术栈 | 通常涉及过时或混合的技术,受限于现有环境。 | 可以自由选择最新、最适合的技术栈和工具。 |
主要关注点 | 稳定性、兼容性、渐进式改进、风险控制、技术债务管理。 | 创新、快速迭代、最佳实践、可伸缩性、未来发展。 |
风险 | 破坏现有功能、引入新 bug、技术债务、兼容性问题。 | 业务模式未验证、市场接受度、初期投入大、技术选型风险。 |
开发策略 | 改造、重构、集成、逐步替换(如绞杀者模式)。 | 从头设计、构建、测试、部署。 |
团队心态 | 谨慎、耐心、注重细节、解决问题、逆向工程。 | 创新、探索、快速尝试、拥抱变化。 |
成本与时间 | 难以准确预估,可能持续投入,维护成本高。 | 初期投入大,但长期维护成本可能较低(如果设计良好)。 |
业务价值 | 维护和提升现有业务,逐步现代化。 | 创造新业务、新市场,或颠覆现有模式。 |
测试 | 挑战大,需逐步建立自动化测试覆盖。 | 可以从一开始就建立完善的自动化测试体系。 |
2.5. 混合模式
Brownfield 和 Greenfield 模式代表了软件开发项目的两种基本环境。
- 一个大型的 Brownfield 项目可能会在现有系统的基础上,引入全新的 Greenfield 模块或微服务,通过 API 与遗留系统进行交互。
- 一个 Greenfield 项目在发展壮大后,其自身也会逐渐积累技术债务,最终演变为一个 Brownfield 项目。
理解它们的区别,有助于项目经理、架构师和开发团队在项目启动时做出明智的决策,包括选择合适的技术栈、制定合理的开发策略、评估潜在风险,并组建具备相应技能和心态的团队。
Brownfield 项目虽然充满挑战,但通过正确的策略和方法,同样能够实现系统的现代化和业务价值的持续增长。
3. 过往 Brownfiled 项目经历回顾
3.1. 几个大的棕地模式项目经历
- 17 ~ 19 年:在环球易购,担任后台研发团队复杂人,负责将一个日订单额过千万的 Ecshop 跨境电商平台重构为微服务架构:https://gearbest.com
- 20 ~ 21 年:在腾讯课堂,负责将日均百万 UV的腾讯课堂帐号系统进行重构,支持多账户登录、帐号开发平台等能力,保障系统用户帐号相关服务的稳定性:https://ke.qq.com
- 21 ~ 22 年:在腾讯课堂,负责将腾讯课堂清分结算系统做演进,支持每月两次结算过亿的清结算系统准确无误的结算
PS. 因为环境变化业务发展原因,这些项目最终都走向了坟墓(PIP),不过期间沉淀的经验还是很宝贵的,所以这里也把之前一些部分资料分享出来,以《腾讯课堂清结算系统》一瞥来理解下棕地模式,说明其复杂性
3.2. 腾讯课堂结算系统背景
腾讯课堂每月两次清结算(T+15)上亿元的平台资金,每次会将过往半月的用户的交易订单额,按结算按一定比例分成给到不同的平台和合作方。
腾讯课堂结算系统需要清晰的统计每笔订单的资金明细以及分账明细,确保满足合规要求。
整体看起来很简单,不过因为课堂经历过 10 多年的产品形态迭代,在收款模式、用户营销、合作伙伴奖励、订单和虚拟单类型、结算策略等一系列模式综合下,整个结算系统复杂性可想而之。加上系统尽力了不同时期、团队、技术栈更迭,导致整体架构极其复杂,整个“棕地模式"的特点(历史代码、架构缺陷、文档缺失、复杂耦合、高风险不确定、业务还需要连续性…)都淋漓尽致体现出来。
过往每次结算都会人工方式在 T-3 之前开始准备,提前检测 DB 数据,好像等待一次次考验,当初自己被调到负责整个结算业务时候,因为耳闻目染过结算系统复杂性以及高风险,倍感压力山大!
先结合旁路新功能业务切入 - 快速熟悉业务
当初个人策略也想得比较清楚,和团队 Leader、产品对齐已有的结算核心问题(结算准确性、人效问题、新功能开发),开始从“结算预测“这一新产品功能,快速理解现有的结算业务。
期间包阅读代码、调试,与业务专家、团队老人交流,重新梳理出系统的现有行为和业务逻辑。
例如当时客户希望有“结算预测”能力,这个能力和实际结算相关,但又不是与结算业务直接耦合,所以可以作为对接手结算系统一个很好切入点。
通过走读代码+残留文档整理 - 逆向工程理解
在做结算预测期间,因为历史文档缺失零散和未实时更新,加上复杂的结算体系,需要从旧文档、人和系统三个角度切入:
- 旧文档:虽然文档比较旧,但也有一定参考价值
- 与业务专家沟通:业务专家和团队老人,都是快速了解业务术语的很好途径
- 代码走读:结合文档、专家沟通结论以及代码三方交叉梳理出最新的系统架构文档信息
逆向工程一瞥:
下图是沉淀出来的关于课堂结算的库表信息,可以看到涵盖了交易订单(包括普通\分期\退款\虚拟单)、结算订单(预测\风控\结算单)等核心表信息
下图是围绕【学员下单】展开,仅普通订单就涵盖的业务知识(支付渠道、订单来源、支付平台、订单状态等等)
梳理规整
熟悉了整个模式后,开启绞杀模式
通过逆向工程对系统有一定了解后,结合产品需求功能痛点,从边缘需求到核心需求对原有系统进行不断解耦拆分,把一些痛点难维护管理的模块进行绞杀替换重构,不断的深入和治理这个极其复杂的业务
结合新产品需求,重新规划
结算重入
结合需求做重构改造,逐步替换
以下是当时结合结算系统的二清需求,在对原有系统有一定理解的程度上,逐步修改和重构原有的结算模块,并引入结算重入、风控设计、结算推送,将结算流程拆分成多个步骤,提升结算系统的输出质量
4. 复杂系统维护心得
4.1. 说明
- 先深入理解现有业务:业务专家、旧文档、走读代码逆向工程交叉深入了解系统,并绘制更新架构、文档信息
- 再逐步管理技术债务:正视债务、优先级、持续重构、预留债务偿还资源
- 拥抱小步和渐进式演进:增量逐步绞杀,而非一步到位,包括 Feat 特性开关、后向兼容考虑
- 强化监控与预警:病重系统更应该上监控,包括日志(清晰可追溯)、系统资源(磁盘\CPU\网络\内存)、应用系统监控(请求量、响应时间、错误率)、告警治理(合理分级、合理阈值、避免淹没重要信息)、故障复盘与演练(找出根因,提升团队韧性和响应能力)
- 团队文化:人是核心,强化生产意识、责任心、积极 CR(内部研讨会、结对编程)、心里安全、认可与鼓励在维护工作中出色成员
- 团队规划:清晰的阶段计划,包括核心事项、技术升级、安全加固,管理好相关团队预期(清晰沟通维护工作的复杂性,所需潜在风险),定期汇报
4.2. 小结
维护复杂系统是一场马拉松,而非短跑,尤其是接手了一个宗地模式的项目~ 它需要耐心、毅力、持续学习和不断适应。
通过上述心得的实践,可以帮助团队更有效地应对挑战,确保系统的长期健康运行和业务价值的持续交付。