为什么遗留系统重构往往以烂尾告终?
老系统核心逻辑交织复杂,原始开发人员多已离职,代码中充满隐蔽的全局变量与副作用。人工重构如同“拆弹”,稍有不慎就会导致线上业务瘫痪。
Agent 辅助渐进式重构实践
- 领域边界拓扑探测:Agent 利用 AST 工具扫描所有类之间的跨包调用次数,自动建议符合高内聚低耦合的限界上下文(Bounded Context);
- 绞杀者模式(Strangler Fig Pattern)渐进替换:不推倒重来,而是由 Agent 在现有单体外围自动生成防腐层(Anticorruption Layer)与转发代理;
- 接口契约全自动提取:分析老系统的入参出参数据结构,秒级生成标准 Protobuf 或 OpenAPI 定义,大幅削减手工建模耗时。
迁移执行的四阶段流程
第一阶段是摸底:让 Agent 静态扫描调用拓扑与数据访问路径,产出一份按变更频率加权的热力图,优先聚焦高频改动区域,大规模仓库的上下文定位可借助混合搜索与 AST 代码索引架构:打造万级文件代码库的高精度定位引擎。第二阶段是定界:对候选限界上下文逐一评审,确认数据归属。第三阶段是替换:在网关层按路由把个别接口切到防腐层,双写或转发到新服务。第四阶段是收尾:老路径流量清零后再物理下线,避免"半拆"状态长期共存。
拆分边界取舍对比
| 判定维度 | 倾向拆出 | 倾向保留 |
|---|---|---|
| 变更频率 | 与主干明显不同步 | 总是同批修改 |
| 数据耦合 | 仅通过服务接口读写 | 直接共享数据库表 |
| 故障隔离需求 | 峰值流量或高风险操作 | 低频后台任务 |
| 团队归属 | 有独立维护者 | 无人认领 |
共享数据库是最高频的伪边界信号:物理上分了服务、逻辑上仍是一张表,后续任何 schema 变更都会把两个团队重新绑在一起,这类模块通常应延后拆分。
验证方法:基线回放与契约比对
切流前必须建立行为基线:录制生产环境的典型请求与响应(脱敏后),在新旧两条路径上回放并逐字段比对,差异清单交给熟悉业务的人裁决而不是自动放行。契约生成后建议做双向校验——用老系统实现验证新契约可被满足,再用契约 mock 验证新服务实现兼容,接口文档与工具定义的自动同步思路可参考接口文档实时同步:基于 CI/CD 自动更新 MCP 工具定义的自动化流水线。
常见故障速查
| 现象 | 原因 | 处理 |
|---|---|---|
| Agent 给出的边界建议频繁变动 | 扫描未加缓存,上下文窗口截断 | 固化调用图快照,按模块分批分析 |
| 防腐层转发后偶发超时 | 新旧路径串行调用叠加延迟 | 为转发设置显式超时与降级开关 |
| 生成的 OpenAPI 与真实响应不符 | 老接口存在未声明的动态字段 | 以流量回放统计补全契约再评审 |
| 拆分后缺陷率上升 | 隐性全局状态未被识别 | 回切流量,补齐副作用清单再迁 |
小结
迁移是否健康,看一条硬指标:任一已切流的模块,其回放比对差异数应当随迭代单调收敛至零,而不是每轮都冒出新差异。若三个月后仍有任何接口无法双跑一致,说明边界判定有误,正确动作是把该模块退回"保留"列,而不是继续堆兼容代码。慢即是快,可回滚的重构才叫重构。