票易通销项域(Phoenix)系统重构调研报告
(另 41 个边界待裁定)
由 32 个仓库支撑
全域最新列车覆盖 0/45
8 组双向环 · 108 张多写者表
域内第一单点 config 上
≈125–155 人月 · 18–20 个月
1 · 执行摘要
1现状一句话
2重构主张
先让系统「看得见、可回滚、可算」,再让结构「可动」。结构收益后置,但每一步独立交付、随时可停、失败可回滚:
- 前 2 个月补齐运维真值——活任务清单、45/45 commit 溯源、探针、in-situ 重跑、配置名称桥;
- 再 3 个月止血与解耦——三个单点降级、共镜像负载拆发版单元、清理 153 个僵尸负载与 9 个重复域名、内部依赖 SNAPSHOT 冻结定版;
- 之后才解环、收敛写者、处理数据与边界——在「爆炸半径可算」之前,不在 16–23 亿行级核心链上动刀。
3量化收益目标(验收口径)
| 指标 | 现状(实测) | 目标 | 达成时点 |
|---|---|---|---|
| commit 可溯源(pod 标签直配) | 34/45(含 tag-fallback 41/45) | 41/45 直配 + 4 豁免 | 2 月 |
| 关键负载健康探针 | 11/51 不达标 | 0 | 5 月 |
| 同一 commit 覆盖的生产负载 | 5 个负载共 sha,12 副本 | ≤1 或登记豁免 | 5 月 |
| 僵尸负载 / 重复域名 | 153 / 10 | 0 / 0 | 5 月 |
phoenix-seller-config 同步声明行 | 825(9 个生产调用方) | <100 | 9 月 |
| 最高频报错「查询用户信息V2接口异常」 | 263 处 / 54 组件 | 根因消除 | 9 月 |
| prod 所载最新列车覆盖率 | 11/45 = 24.4%(全域 0/45) | ≥70% | 9 月 |
| 双向环 | 8 组 | ≤2 组 | 14 月 |
| 10 张四写者表的生产写者 | 3 | 1 | 14 月 |
| 表级所有权清晰度 | 73.0% | ≥90% | 14 月 |
共享实例 2711414 故障域 | 一实例 24 库 / 1417 连接 / 24 账号 | ≤10 库、连接 −50% | 18 月 |
4代价与边界(买的是什么)
投入
- 总投入 ≈125–155 人月 / 18–20 个月(四方案竞标后收敛;原始四方案区间 113–205);
- 峰值团队 12–14 人(含 2 名 DBA、2 名 SRE);
- 阶段 0(5–7 人月)不依赖任何前置条件,可立即启动。
明确不做
- 不做领域边界重划落地(14 个域只作目标语言,不作前置门禁);
- 不拆
phoenix-bill与phoenix-seller-invoice两个巨石; - 不做核心链物理拆库——只交付「写者收敛 + 影子比对机制」;
- 不做 Spring Boot 3.x 大迁移、不做前端重写、不动 LMT 与属地化。
2 · 调研方法与证据体系
1证据来源:研发本体湖仓(OntoOS)
调研基于统一编目的研发本体湖仓(AnalyticDB-PG 五层架构:ODS / ODS_CURRENT / DWD / DWS),覆盖 8 大数据域:GitLab 项目与流水线、Kubernetes 工作负载(14 个集群)、阿里云 DMS 数据库实例/库/表/列、Apollo 配置中心、容器镜像反解出的代码结构(Spring 端点 / MyBatis / Feign / MQ / 前端路由与 import 图 / 业务枚举 / 错误签名)、门户菜单注册中心(页面业务名词 → 微应用 → 仓库)、网络接入层(DNS/WAF/SLB/ALB)、ECS 载体。此外对销项主库做了真库只读直连抽样(2026-09-11 活态)。
| 数据域 | 关键口径 | 快照时点 |
|---|---|---|
| GitLab 仓库 | 全库 1,976 个项目 → 销项 in-scope 77 个 | 2026-09-04 |
| K8s 生产部署 | 20-phoenix-prod 唯一在线中心产线(45 活跃负载 / 94 副本) | 2026-09-04 |
| 代码结构归档 | 全库 3,685 镜像 → 严格销项组 187(白名单口径 268) | 2026-09-05 |
| 数据库(元数据) | DMS 纳管实例/库/表(销项中心 prod 14 实例 / 27 库名 / 1,551 表) | 2026-09-04 |
| 数据库(活态) | L14 真库直连抽样:规模 / 连接 / 视图 / 账号级证据 | 2026-09-11 |
| Apollo 配置 | 销项相关 18 应用 / 生产配置真值核对 | 2026-09-04 |
| 在线内省轨(in-situ) | 1,065 个活进程内省 source——冻结在 2026-07-01,已停滞 72 天(凡引用处均标注) | 2026-07-01 |
2调研工作流:四段式多代理pipeline
3范围界定:三个高危误判陷阱(已量化)
销项域与进项域、内部计费域、票税客户端在命名上高度纠缠,直接用关键词检索会产生系统性误收——范围文件把三个陷阱都做了量化并给出负向过滤:
| 陷阱 | 规模 | 说明 |
|---|---|---|
phoenix-purchaser(进项域) | 47 仓 / 137 镜像 | 按 %phoenix% 统计会把进项算进销项,规模虚高 37%(375 → 真实 238) |
p0121-phoenix-prod(4.x 老产线) | 114 个 Deployment | 全部 replicas=0,是 2018 年的 Choerodon 老系统,任何把它当 prod 的调研都会得到完全错误的结论 |
| 门户微应用(前端主体) | 465 个微应用 / 76 模块 | 前端三仓不产镜像、不进 K8s,只按容器清点会把销项前端主体整个漏掉 |
最终口径 = 「命名空间 ∪ 仓库白名单」并集:77 个 in-scope 仓库(T1 核心 45 + T2 销项服务 30 + T3 AI 扩展 2),另有 41 个边界仓待业务裁定、123 个明确排除。
3 · 现状全景
3.1资产盘点:77 个仓库、45 个生产负载
仓库活跃度:两极分化严重
77 个在范围仓库中,真正跑在生产(replicas>0)的只有 30 个;其中 9 个「冻结但在线」——超过 180 天无 git 提交却仍在生产运行,最长 641 天 / 4 副本(phoenix-customer-self-ops)。
技术构成
- 语言:Java 49 仓(63.6%)、JS 14、TS 7、Vue 3;
- 运行形态:
spring30 /fe13 /oqs(低代码运行时)6 /gateway1; - 两套主框架并行:Spring Boot 版本在 34 个后端负载上分属 11 个不同版本,JDK 4 档并存,底座基础镜像 12 种。
生产负载构成(45 个 / 94 副本)
- 按部署分支:14 条分支/标签并存,最新列车仅 11 个;
- 按仓库:32 个去重仓库——
athena-elastic-consumer一仓十役(10 个负载 / 7 个镜像 tag,靠 4 条分支区分角色)。
3.2业务能力地图:23 项能力,65% 压在 3 个服务上
从门户菜单(2,276 个逻辑菜单)与错误码/枚举反查,共归纳出 23 项销项业务能力。承载集中度极高:
「重复实现」有指纹级证据:同一套业务语言被独立设计了多次——
| 重复对象 | 副本数 | 说明 |
|---|---|---|
InvoiceType(票种枚举) | 21 个 FQCN 变体 | 分布在 88 个组件中,同一票种语义 21 次独立设计 |
ErrorCodeEnum(错误码) | 12 变体 / 954 entry | 去重后仍有 954 个条目,错误语义全域无唯一源 |
SALEIV# 业务错误码(189 个) | 分散 4 个仓 | phoenix-seller-open-api(138) / phoenix-openapi(123) / phoenix-bill(122) / phoenix-seller-invoice(49) |
| Ticket Token 刷新任务 | 19 个任务 / 10 个服务 | 7 份同名类各写一遍(调度重复实现的典型) |
| 票税云客户端 | 8 个仓 / 4 个逻辑名 | 同一外部厂商被 8 个服务各自实现客户端 |
能力与承载的对应表(节选):票池 3 套并行、开票主数据(抬头)4 仓建模、税编 3 仓、运维台 4 套、开票链路 4 个服务各有实现。l12-capability-map.csv l12-enums.csv l12-errors.csv
3.3数据资产与规模(真库活态实测)
约 204.8 亿行
27 个库名 / 1,551 张表
其中 9 张达四写者
最大表与最大库(2026-09-11 直连实测)
inv_seller_invoice_item 为 PRIMARY(16.35 亿)+ SHARD01(12.71 亿)合计(验证订正 C22);ord_salesbill_item 为单表单分片行数第一、容量第一(2.34 TB)。
库规模
sellerinvoicePRIMARY:7.59 TB / 98.0 亿行;SHARD01:4.02 TB / 55.8 亿行(两分片合计 11.6 TB / 153.8 亿行);bill链:5.19 TB / 51.1 亿行;- 分片键
seller_group_id,DDL 必须双库同步。
共享实例 2711414(4.0_si_element-prod-db)
- 一实例承载 24 个库(销项 19 + 非销项 5);
- 在线连接 1,417 条 / 24 个账号(29 为账号×库组合数),为全域最高;
- 9+ 个服务的故障域被物理绑定在一起。
数据所有权成熟度:73.0% 清晰 / 21.6% 需治理
两个枢纽服务制造了绝大部分共享:phoenix-script-invoice(238 表 / 235 张被写)出现在 100/117 张共享表、98/108 张多写者表里;phoenix-openapi(36 表中仅 5 张专属 = 14%)直连 8 个库读写。
l14-live-sampling.csv · l14-live-top-tables.csv · l7-multi-writer.csv · l7-service-table-counts.csv · 02-analysis/02-data-architecture.md
3.4运行拓扑:极端中枢型依赖 + 双向环
销项域内部同步调用(Feign)共 104 条边,4 个服务占了内部入度的 87.3%(合计 2,523 行声明):
8 组双向 2 跳循环(节选)
bill ⇄ seller-invoice:311 / 303(近对称,最重)bill ⇄ config:371 / 20inventory ⇄ config:14 / 20casm ⇄ config:10 / 37- …另有 4 组(
bill⇄casm、casm⇄invoice、invoice⇄smart-match、open-api⇄source-bill)
MQ 与消息
- 全域 6,315 条 MQ 操作 / 767 个通道;
- 通道闭合率仅 3.5%(28/803)——但这是抽取偏斜而非可靠性指标:发送侧物理名解析率仅 0.1%;
- 真实治理面:24 条自研
xplat-sqs开票主链通道全闭合,而 rabbitmq/rocketmq/jms 闭合率 0–1.9%;9 条发送无接收(send-unpaired)通道待逐条定性。
l4-feign-edges.csv · _l4-degree.txt · l5-summary.csv · l5-closure-pairs.csv
3.5前端与外部集成
前端:门户注册中心驱动的「微应用农场」
- 23 个 FE 仓、3 类载体(门户微应用 465 个 / 独立容器 6 / 移动端小程序 5)、三代技术栈 6 套构建管线并存;
- 前端主体三仓(
seller-main-fe219 /seller-config-fe210 /auto-billing36 个微应用)在湖仓中构造性不可见:不产镜像 →k8s_containers与code_archives均为 0; - 「销项门户 → 销项后端」链路当前完全不可测(
v_fe_to_be.fe_workload100% NULL)。
外部集成:碎片化,且「税局直连」是误解
- 票税云厂商被 8 个仓各自实现客户端(至少 4 个 feign 逻辑名并存);
- 逐条判读 283 个外呼 URL:无 chinatax/etax/leqi 类直连——中心销项域统一收敛为票税云网关;真正的准直连通道在 LMT 侧(公网 IP + 明文 broker);
- 4 个租户前缀、3 个开放平台、9 条路由塞在一个网关,无统一集成网关/适配层。
01-inventory/08-frontend.md · 02-analysis/05-integration-frontend.md · l3-endpoints-prod.csv
4 · 六大病灶诊断
P1边界缺失与重复实现 严重
销项域的病根不是「服务太多、代码太老」,而是边界从未被定义过:65% 的业务能力集中在 3 个服务,同一业务语言被独立设计 21 次。
| 现象 | 关键数字 | 影响 |
|---|---|---|
| 能力集中 | 3 个服务并集承载 15/23 = 65% 业务能力 | 任何改动的影响面都不可控 |
| 能力多副本承载 | 8 项能力被 ≥4 个后端仓同时承载(开票/预制发票/红字/智能匹配/票池/抬头/运维台…) | 新增票种/渠道要改 N 处,边际成本高 |
| 语义分裂 | InvoiceType 21 个变体、ErrorCodeEnum 954 个去重条目 | 数据语义跨服务不一致 |
| 技术组件冒充业务服务 | 4 个生产服务按「业务服务」计入 45 个负载,实质是通用支撑(文件/同步/网关/Flink 底座) | 盘点口径失真、边界评估错位 |
| 「假叶子」陷阱 | kaipiao-center Feign 图双向孤立(出/入度均为 0)却承载 655 个生产端点 / 96 个 controller 与公网入口(真实调用方是 H5/小程序与第三方回调,不在代码湖) | 按依赖图下线服务会系统性误判 |
02-analysis/01-domain-boundaries.md · l12-capability-map.csv · l12-enums.csv · l12-errors.csv
P2数据耦合与「暗数据层」 严重
一切耦合的物理根在数据:一实例 24 库、108 张多写者表、租户定制渗透中心主库、绕过发布的手工变更通道。
| 现象 | 关键数字(实测) | 风险 |
|---|---|---|
| 共享实例故障域 | 2711414 一实例 24 库 / 1,417 连接 / 29 账号,9+ 服务在其上 | 一次实例级故障 → 9+ 服务同时不可用 |
| 多写者表 | 500 张表中 108 张多写者;10 张四写者表(发票链 6 + 业务单链 3 + t_elastic_config) | 任何一方改数据语义都会静默影响他方 |
| 写者枢纽 | script-invoice 参与 98/108 张多写者表、100/117 张共享表 | 一个「客户迁移脚本仓」成了全域最大共享写者 |
| 租户「暗层」 | 主库上 8 个 DBA 手工视图(v_vanke_*×4 硬编码 '182'、v_wilmar_*×4 硬编码租户 ID),DMS 台账完全不可见 | 改表结构会静默打断租户功能,无测试无监控能发现 |
| 绕过发布的变更 | cfg_config_item_bk09081451(9-8 新建,998 万行)、ord_salesbill_history(9-8 改名换表) | 存在手工修数通道,代码仓库与发布流程均无记录 |
| 权限与纳管缺口 | root(疑 root@%)在 4 台实例各有 5 条连接(共 20 条);17 个 host 未被 DMS 纳管(其中 7 个为真正未纳管的 RDS 域名) | 生产连接真值无单一系统可答 |
| 域外直连 | 8 个域外 namespace 直连销项库(sa-maintenance 7 库、蚂蚁协同直连 sellerinvoice…) | 销项拆库的可行性被域外读方阻断 |
02-analysis/02-data-architecture.md · 01-inventory/14-db-live-probe.md · l14-*.csv · l7-multi-writer.csv · l6-orphans.csv
P3单点、环与发版爆炸半径 严重
| 风险点 | 证据 | 失败形态 |
|---|---|---|
全域第一单点 phoenix-seller-config | 9 个生产服务同步依赖、声明行合计 823、56 个 Feign 接口;且兼做用户中心门面——10 个调用方全部声明 /user-center 路径,其中 3 个对该路径只有 1 个命名接口(仅 walmart-sync 只此一条依赖) | 它挂 → 9 个服务阻塞。全域最高频报错「查询用户信息V2接口异常」263 处 / 54 组件即源于此 |
phoenix-bill 三料叠加 | 同步入度 627(第二)+ MQ 第一枢纽(send 529 / recv 1654 / 106 通道)+ 数据量第一(23.1 亿行表) | 任何维度的故障都放大到全域 |
双向环 bill ⇄ seller-invoice | 311 / 303 近对称;其 15 个契约接口签名不在任何销项仓源码里,而在 Nexus 制品 bill-client:4.2.3-SNAPSHOT(其中 11 个是空壳) | 改任意一侧 → 爆炸半径无法计算 |
一仓十役 athena-elastic-consumer | 10 个生产负载 / 7 个镜像 tag;5 个负载共用同一 commit(12 副本)、4 个共用同一 tag(10 副本) | 一次错误发版同时崩掉 ES 检索面全部入口(「能开票、查不到票」的半损故障) |
调度大脑裸奔 xck-job-v2-a20a5 | 单副本、2020 年镜像(2,285 天)、无 liveness 探针、承载 139 个 job 入口 | 挂掉即全域定时任务停摆 |
02-analysis/03-runtime-dependencies.md · l4-feign-edges.csv · _l4-degree.txt · 01-inventory/13-code-deepdive.md
P4交付僵化与构建不可复现 严重
发布列车只是分支命名约定
- 45 个负载分属 14 条分支/标签;最新列车(release-20260818 + hotfix)覆盖仅 24.4%;
- 同一列车三种写法并存(
release/20260818与release-20260818,还有多一位的release-202608018); - prod 落后 fat 整整一条列车(release-20260915 在 fat 有 10 个、prod 0 个),「fat 验证过 = 安全」的假设不成立。
镜像僵化 + 构建不可复现
- 镜像 tag 年龄中位数 238.5 天,16 个(可判定者中 38%)超一年未更新;最老 2,285 天;
- 三环境皆有的 18 个服务中镜像完全一致的只有 4 个(22%);
- 内部依赖 70.1%(195/278)含 SNAPSHOT 版本——同一 commit 两次构建产物可能不同,「可回滚」在依赖定版前不成立。
02-analysis/06-ops-delivery.md · 02-analysis/04-tech-debt.md §D1 · l2-prod-workloads.csv · l11-internal-libs.csv
P5集成碎片化与消息治理空白 中等
- 票税云 8 个仓各自实现客户端(≥4 个逻辑名)——对同一外部厂商 8 份实现、8 份凭证、8 份重试逻辑;
- 重试与补偿全部退化为定时扫表:无 HTTP/MQ 级统一重试语义,幂等无任何证据(开票是合规链路,重试造成重复发票对客户有实际影响);
bill-engine的 5 个 Kotlin@RabbitListener全写成匿名Queue(),致 55 条 binding 不可治理;9 条 send-unpaired 通道待逐条定性;- 前端主体 465 个微应用在湖仓零源码画像——「销项门户 → 销项后端」链路完全不可测。
02-analysis/05-integration-frontend.md · 02-analysis/03-runtime-dependencies.md §2.4 · l5-orphan-channels.csv
P6治理真空:运维真值不在 Kubernetes 中等
| 真值对象 | 实际所在 | K8s 侧现状 |
|---|---|---|
| 业务配置 | Apollo(18 应用 / 38 个 (host,db) 连接) | 业务 ConfigMap 0 个;366 条 env 中 0 条 configMapKeyRef |
| JDBC 连接 | Apollo | 51 个负载只解析出 1 条 JDBC(且属域外调度件) |
| 定时任务 cron | MySQL(xxl_job_v2.xxl_job_info 820 行) | 73.1%(1204/1648)任务 cron 不可见;139 个 xxl-job 全在 MySQL 里 |
| 可观测性 | ELK 只在 sit(6 个负载);APM 缺失 | prod 与 fat 可观测性负载 为 0 |
| 健康探针 | — | 11/51 不达标(10 个无任何探针) |
| 4 个关键分析视图 | — | 结构性失效(0 非空 / 100% NULL):v_insitu_config_truth_diff.ds_config_hostport、v_fe_to_be.fe_workload、resolved_path、v_workload_db_traffic.dms_db_id |
叠加 in-situ 在线内省轨停滞 72 天(1,065 个 source 冻结在 2026-07-01)、6 个死命名空间躺 153 个 0 副本负载、9 个域名与生产重复注册(含主域)——现状是「漂移不可见、治理无抓手」。
02-analysis/06-ops-delivery.md · 02-analysis/04-tech-debt.md §D5/D6 · l2-services.csv · l6-orphans.csv
5 · 重构方案
5.1四方案竞标与交叉评审
4 位设计师从不同战略角度各自独立完成了一份完整重构方案(互不可见),再由 4 位评审从不同视角交叉打分:
| 方案 | 战略论点(一段话) | 投入估算 | 工期 |
|---|---|---|---|
| A · 领域驱动 业务边界优先 |
病根是「边界从未被定义过」——第一交付物不是代码而是领域边界与契约(14 个 bounded context),服务与数据归属跟随领域,契约先行。 | ≈155 人月 (最小可行版 80) |
21 个月 |
| B · 数据优先 先拆共享数据层 |
一切耦合根因在数据层:先动数据所有权(拆库、双写过渡、读模型、大表治理),服务拆分跟随数据边界自然发生。决定性优势:JDBC 真值 100% 在 Apollo,换库地址不改一行业务代码、分钟级可回滚。 | ≈113 人月 (坏情景 139–150) |
14–16 个月 |
| C · 渐进平台化 Strangler + 能力下沉 |
最大成本不是边界画错,而是平台层缺位。先用 9 个月补齐 6 项平台能力(发布列车、SNAPSHOT 定版、配置/用户中心下沉、契约注册中心、统一集成层、可靠性组件),再让业务逐个软迁移。 | 56–76 人月 (平台侧)+ 业务侧 8–12 |
12–18 个月 |
| D · 稳定优先 先止血,再结构 |
最贵的不是「边界不清」,而是边界不清的地方此刻还带着单点、环、看不见的消息和没纳管的库在生产上跑。先补运行真值/可观测/探针、单点降级、发版单元解耦、僵尸清理,再解环、收敛写者。 | 170–205 人月 | 18–20 个月 |
评审打分矩阵(0–10,每列一个独立视角)
| 方案 | J1 可行性与风险 | J2 证据支撑与一致性 | J3 业务价值与收益 | J4 落地成本与组织承受 | 均分 |
|---|---|---|---|---|---|
| A 领域驱动 | 4.0 | 7.6 | 6.0 | 4.4 | 5.5 |
| B 数据优先 | 6.5 | 7.0 | 4.0 | 4.8 | 5.6 |
| C 渐进平台化 | 5.0 | 6.7 | 7.0 | 7.3 ★ | 6.5 |
| D 稳定优先 | 7.5 ★ | 8.3 ★ | 7.5 ★ | 6.2 | 7.4 |
★ = 该视角第一名。评审要求「禁止和稀泥」:分数必须有区分度,问题必须给到方案的具体章节。
评审的关键发现(摘要)
- 不选 A 的理由:关键路径压在一个本体未取到的 Nexus 制品(
bill-client)上,且收益押在一次方案自身不拥有、不计价、不控制的组织改造(14 个域 owner 任命)上;报价 155 人月与其单价明细不自洽。 - 不选 B 的理由:主体交付建立在从未评估的前提(业务只读窗口 / 在线 DDL 能力)上;「Apollo 一处切换、零代码改动」的承重结论在风险最高的写者
phoenix-script-invoice上恰恰不成立(170 个配置项全在 SIT、PROD 为 0)。
- 不选 C 的理由:每步都落得下去,但结构收益锁在双重门禁后,且阶段 4 报价(8–12 人月)与其余三份对同一物理工作量的报价(B 34 / D 110–130)差一个数量级。
- 选 D 的理由:关键路径建立在已取到的事实上;实抽 18 条数字零失真、不把弱证据当强证据用;收益密度与可验收性最高;每步可独立交付、随时可停。
5.2最终方案:五阶段路线图
绿色 = 不依赖任何前置条件可立即启动;斜纹 = 条件启动(P0–P3 全部达标才启动,且不带工期承诺)
seller-config:剥离 3 个只用 /user-center 的调用方 + 读取加本地缓存与超时降级 + 收敛 19 个 Token 任务;② athena-elastic-consumer:只改 CI/发版粒度不改代码,为共 sha 负载建独立发版记录与告警;③ 契约定版第一波(只冻结、只提签名、不改语义):seller-common-tools、bill-client 反编译提签名、bizorder.* 解包、xlog-* 冻结;④ 集成收口:9 条 send-unpaired 定性、匿名 Queue 具名、票税云客户端 8→1;⑤ 僵尸清理(只清零环境备案者);⑥ 配置真值补全。
验收无镜像 tag 覆盖 >1 生产负载(或豁免);探针缺口清零;完成一次「config 整体不可用」演练,证明 9 个调用方降级而非阻塞;定版 + CI 禁 SNAPSHOT;153 僵尸负载删除、9 域名摘除。
风险Token 任务触 10 服务启动逻辑 → 旧任务保留一版双跑;反编译失败 → fallback = 调用方反推 + 流量录制。
workload_name)+ 两个 SLO + JDK 随 CI 参数切换;② 契约注册中心:bill-client 等 3 族契约落入可见仓 + CI 兼容校验;③ seller-config 读路径下沉 SDK(本地缓存 + config.changed 失效,目标 825 → <100 而非清零);④ 可靠性组件:幂等表 + 统一重试 + 事件补偿(复用 xtask);⑤ 可观测性全量补齐。
验收每个列车日期只剩 1 条分支;台账 45/45;SLO 自动可算;镜像 >365 天者 16 → ≤8;覆盖率 ≥70%;契约仓列出 15 个签名;config 声明行 825 → <100。
风险SLO 数据源(流水线全 0 行)→ 台账 + 镜像 tag 双源校验;配置 SDK 引入缓存不一致 → 单调版本号 + TTL 兜底 + 按服务灰度。
phoenix-bill、发票状态归 seller-invoice;② 写者收敛(应用层先行、表不离库):script-invoice 拆为「一次性脚本归档」与「管理 API」、openapi 从直连多库写改为编排 + 订阅;③ 2711414 故障域隔离(只隔离不搬迁);④ 租户暗层归零(8 视图参数化后删除、root@% 下线、17 孤儿 host 纳管);⑤ 读模型下沉(5 张读热点表);⑥ 大表归档。
验收8 组环 ≥6 组消解;四写者表写者 3 → 1;script-invoice 写表 235 → ≤10;清晰度 73.0% → ≥90%;2711414 库数 ≤10、连接 −50%。
风险16–23 亿行级表不承担物理拆库;改表结构会静默打断 8 个视图与 ES 索引(binlog CDC)→ 迁移前做影响扫描;事件化只限状态跃迁(合规链路保持强一致)。
COUNT(*);跨域资产一律先协商,归属未定者只隔离不搬迁。
5.3目标架构(五视角终态)
5.4每阶段验收口径(汇总)
| 阶段 | 可量化验收(全部可被只读查询复核) |
|---|---|
| P0 | 45/45 commit 溯源 · 名称桥 ≥40/45 · 4 个失效视图恢复 · in-situ 新批次 · 探针生效 · APM 试点 ≥2 |
| P1 | 探针缺口 0 · 9 通道 100% 定性 · 定版 + CI 禁 SNAPSHOT · 票税云 8→1 · 153 僵尸 + 9 域名归零 · config 演练通过 |
| P2 | 列车日期唯一 · 台账 45/45 · SLO 可算 · 镜像 >365 天 16→≤8 · 覆盖率 ≥70% · config 825→<100 |
| P3 | 环 8→≤2 · 四写者 3→1 · script-invoice 写表 235→≤10 · 清晰度 ≥90% · 2711414 ≤10 库 |
| P4 | 每域独立实例(或库)· 多写者表归零 · 跨域直连连续 2 季度为 0 |
5.5关键取舍
采用的 13 条决策(精选)
- 14 个域作目标语言,不作前置门禁(避开工程侧推不动的等待点);
- 先收敛应用层写者,再评估物理拆库——跨表事务绑定让「拆表」实为「拆写者」;
- 禁双写,用「读旧写新 + 影子比对」(本域无双写实践证据);
- SNAPSHOT 先冻结为已 tag 快照,再逐族发正式版;
- 为
bill-client补反编译 + 签名提取(只提签名、不改语义); athena只改 CI/发版粒度、不改代码;台账键用workload_name;- 迁移用「冻→影→切→收」+ 差异归零门禁,校验一律
COUNT(*); - 对外契约冻结一年、只加不删;只对状态跃迁事件化(合规链路保持强一致);
- 底座随 CI 参数切换,不做 Spring Boot 3.x 大迁移;
- 前端只保证服务端旧路径兜底,不重写、不排期。
不采用的 8 条(精选)
- 领域边界书面裁定不作硬门禁(改为北极星 + 待决项);
- 契约先行到「先冻结契约再动服务」→ 会让前期 5 个月零业务价值,改为与止血管线并行;
- 枚举收敛不急进:票种至少 7 套编码体系,合并 FQCN 若触及持久化编码即数据语义变更;
- 库搬迁优先不外推到大库(只在私有小库成立);
- 「Apollo 改地址 = 零代码改动」不作全称结论(对否定性证据过度外推);
- 「不做数据物理迁移」的整块排除不采纳——区分「隔离」(承诺)与「搬迁」(选做)。
三处事实订正(四方案共有的引用错误,已修正)
SALEIV#错误码的仓分布已订正(实为 open-api/openapi/bill/seller-invoice);athena的镜像基数已订正(10 负载 / 7 tag;4 负载共 tag = 10 副本;5 负载共 sha = 12 副本);- 「与 config 相关的环」已订正为 3 组;四写者表实为 10 张(第 10 张
t_elastic_config)。
5.6开放决策与失败判据
开放决策(留给业务/管理层裁定)
| # | 决策项 | 不裁定的后果 |
|---|---|---|
| O1 | 4 处「开票前置能力」(报表 / 渠道开票 / 税控设备托管 / 低代码运行时)是否纳入范围 | 任何方案都不覆盖开票业务的完整链路(无设备无法开票) |
| O2 | xf-bm-xplat-msg 组 15 个边界仓归属(拆票 / 开票要素 / 回调…) | 拆票与开票要素边界悬空,业务单域归属无法确定 |
| O3 | phoenix-casm-service(客户档案)域归属(跑在 bizorder 命名空间,与 bill/casm/invoice 各成环) | 两组环无法在销项内部解开 |
| O4 | 与进项共用的 xxl-job 调度中心迁移方式 | 迁移会丢失全部调度入口,跨域资产中最高危 |
| O5–O7 | 14 个域是否合并为 8–10 个 · 租户寄生库去留 · 业务是否需要「能力可组合」 | 影响 2 年后的接棒方向 |
| O8 | 产能基线:本域现有可用研发人力(四份方案共用 4 套团队假设) | 所有报价的分母缺失;14 人峰值可能等于占满整个销项后端团队 |
| O9 | 是否为「停机窗口 / 在线 DDL 能力」做一次评估(从未评估) | 阶段 4 的物理迁移只能停留在「不承诺」 |
| O10 | 单价对齐:同一物理工作量在三份方案里报价差 2–5 倍 | 拿不同报价做出的预算决策会互相冲突 |
失败判据(何时应停止/回退)
| # | 触发条件 | 动作 |
|---|---|---|
| F1 | bill-client 反编译失败且 fallback 2 个月不可行 | 停止契约注册中心与解环,只保留「冻结 tag」 |
| F2 | APM 3 个月内无法铺到 ≥8 个核心服务 | 停止一切「优先级排序」,退回拓扑宽度排序 |
| F3 | 写者收敛差异清单连续 14 日不为 0(引入数据错) | 回退到读旧写新前状态,冻结该链所有动作 |
| F4 | 「config 整体不可用」演练失败(调用方阻塞而非降级) | 不得进入 SDK 下沉,先补降级路径 |
| F5–F8 | 组织 6 个月未裁定 O1–O3 · 关键人被抽走 ≥4 周 · 超 155 人月未达 P3 验收 · 只读窗口不可得 | 对应降级:解环范围收窄 / 暂停当前段 / 停止剩余阶段 / P4 退化为只做隔离与归档 |
6 · 可信度与对抗验证
1验证方法与统计
验证采用对抗性设计:每条论断由独立代理「尝试证伪」——能重查的用本体重新写 SQL 复核(如「9 个服务依赖 config」重新数一遍依赖边),重查询不便的核对原始证据记录的精确口径;同时由一名完整性批评员审查「未验证假设 / 未跑的模态 / 证据链薄弱 / 方案与证据错位」,高严重度缺口派定向补查,最后由总架构师做保守修订(只订正事实与口径,不改方案结构)。
- 27 条 confirmed——独立复核一致(如「23 项能力中 3 服务并集 15 项 = 65%」「InvoiceType 21 变体 / ErrorCodeEnum 954 条」「2711414 一实例 24 库」「8 组双向环」等全部核验通过);
- 22 条 partial——方向正确但数字/口径/限定词有出入,逐条订正(见下);
- 1 条 refuted——被证伪并改写(C11,见下);
- 0 条 unverifiable——全部论断都有可复核路径。
验证规模:17 个代理 · 317 万 token · 1,298 次工具调用;产出 10 份分组验证报告 + 1 份完整性批评(8 项高严重度缺口)+ 4 项缺口定向补查,最终落入 03-plan/revision-log.md 与方案 V1.1 修订记录。
2被证伪的论断(C11):一个「改对了方案」的证伪
bill-client:4.2.3-SNAPSHOT 中(11 个空壳)」。
验证结论:refuted。签名本体就在销项仓内——
xf-bm-xplat-msg/phoenix-bill 的 bill-client 模块(15/15 接口均有 git 跟踪的 .java 源码,479 个 Java 文件,模块版本与调用方依赖坐标逐字相同)。真实情况是:调用方仓里的 15 个接口中有 14 个是零方法体空壳(原估 11 个偏低),签名本体在被调方仓、调用方以 SNAPSHOT 制品编译期依赖。
对方案的影响(正面的):爆炸半径分析可以直接读该模块源码,不必先解 jar——契约先行的关键路径风险大幅降低;风险重述为「SNAPSHOT 制品与任一侧当前源码可能不一致」。方案阶段 1 已据此从「反编译提签名」改写为「契约提取 + 源码对齐」,失败判据 F1 同步更新。
3典型口径订正(22 条 partial 中影响最大的)
| 编号 | 原表述 → 订正后 | 为什么要较真 |
|---|---|---|
| C02 | 「11 个负载连 commit 都追不到」→ 4 个(另 7 个已由 tag-fallback 离线还原 commit;目标是「pod 标签直配 41/45 + 4 豁免」) | 把已可溯源与真盲区混为一谈,会虚增风险面、误导阶段 0 工作量 |
| C17 | 「13 个库 / 29 个账号」→ 24 个库(实查 dms_databases)/ 24 个账号(29 是「账号×库」组合数) | 故障域规模被低估近一半;口径混淆会把组合数当账号数 |
| C22 | inv_seller_invoice_item「16.35 亿行」→ 29.1 亿行(PRIMARY 16.35 + SHARD01 12.71 亿);按行数的最大表易主 | 分片表只算一半,归档与容量规划会错 44% |
| C23 | 「16.05 TB」→ 16.03 TB(两链核心,二进制口径);旧值含同批采样的 sellerconfig/ccag 且混用十进制 | 容量口径不统一,验收数字无法对齐 |
| C25 | root 连接「3 台实例」→ 4 台实例各 5 条(共 20 条) | 安全面清单少列一台实例 |
| C03 | 「最新列车覆盖率 24.4%」→ 「prod 所载最新列车覆盖率」;全域最新列车(0915)prod 覆盖 0/45 | 基线 24.4% 与目标 ≥70% 必须测同一件事 |
| C04 | 「16/45 超一年」→ 16 个(可判定者中 38%),3 个无法判定 | 分母不诚实的百分比 |
| C08 | 「3 个只用 /user-center 这一条」→ 3 个对该路径只有 1 个命名接口,仅 walmart 只此一条依赖 | 改变动作前提:剥离后 casm/script 仍保留 1 条依赖 |
| C26 | 「证明存在手工变更通道」→ 「给出两处物证」(改名换表是推断,rename/truncate 无法区分) | 把推断写成实测是证据纪律问题 |
| C45 | 「15 项 = 65%」→ 口径补全(严口径 65%,仅排除推断项则为 69.6%) | 剔除规则与数字必须自洽 |
4完整性批评:8 项高严重度缺口
批评员以「一份交给管理层的方案还差什么」为标准,识别出以下高严重度缺口(均已登记,部分已补查):
| # | 缺口 |
|---|---|
| H1 | 阶段 0 三处验收被「第二个未纳管的 Apollo 实例」与「4 个无仓负载」封顶——自检表「纯既有数据 ✅」不成立 |
| H2 | 入口层(DNS→WAF→SLB/ALB)从未盘点:「9 个重复域名」只有 Ingress 声明侧证据 |
| H3 | 库地址「持有者清单」未做,而方案以「一处切换、分钟级回滚」为前提(实测同一库地址被 5–6 个 app 声明,3 个属域外,不在协商清单内) |
| H4 | KPI「清晰度 73.0% → ≥90%」缺少对应工作包 |
| H5 | 「最高频报错 263 处」是静态计数被当作运行频次(已补「代码点位(非运行期频次)」限定) |
| H6 | ≥5 条验收项在现有证据下不可测或不可达(已逐条标注) |
| H7 | 跨域对手方清单不完整(补查已扩充) |
| H8 | 备份/恢复与数据保管合规零覆盖,而阶段 3/4 要动 16 TB 与 29 亿行级表——建议下一轮补专题 |
5遗留给下一轮的不确定性(诚实声明)
- 第二 Apollo 实例未纳管:「哪些负载读哪个 Apollo」仍是硬盲区——重跑 in-situ 轨(阶段 0 ⑤)是唯一既有通道;
- 上游证据文件的个别缺陷未回灌(如
l1-activity.csv双通道未去重、若干枚举小计不一致),本轮只在方案内加注; - 结构性缺口(H8 备份合规、入口链盘点、KPI 工作包等)属「方案缺失内容」而非事实错误,本轮保守修订未新增章节/预算,已登记待下一轮;
- 数据时效:K8s/GitLab/Apollo 快照为 2026-09-04(滞后 5–7 天),in-situ 轨停 2026-07-01——凡涉及「最新部署状态/活进程配置」的结论均需重抽后复核。
7 · 附录
7.1证据索引(全部产出物)
| 目录 / 文件 | 内容 | 数量 |
|---|---|---|
00-scope.md | 范围基线:域边界判定、77 仓清单、prod 服务→仓库映射、可复用白名单 SQL、6 项已知盲区 | 1 份 / 432 行 |
01-inventory/ | 14 条证据盘点线:仓库 / 部署 / 接口面 / 依赖 / MQ / 数据库 / 数据耦合 / 前端 / 配置 / 调度 / 技术栈 / 业务能力 / 代码实证 / DB 实态 | 14 份 |
02-analysis/ | 6 项横向分析:领域边界 / 数据架构 / 运行时依赖 / 技术债 / 前端集成 / 运维交付 | 6 份 |
03-plan/ | 4 份竞标方案 + 4 份评审 + 最终方案(V1.1)+ 修订日志 | 10 份 |
04-verify/ | 10 份分组验证报告 + 完整性批评 + 4 项缺口补查 | 15 份 |
evidence/ | 原始查询输出(CSV)+ 逐线 SQL 记录(queries-*.md,17 个文件) | 176 个文件 363 条查询 |
全部产出共 45 份报告 / 约 169 万字节 markdown / 176 个证据文件 / 363 条逐条记录的 SQL。复核方式:任取一条结论,按 queries-*.md 中的记录(用途 / SQL / 输出文件 / 行数)重跑即可——
7.2生产服务清单(20-phoenix-prod · 45 个活跃负载)
| 工作负载 | 副本 | GitLab 仓库 | 部署分支 |
|---|---|---|---|
| bill-engine | 2/2 | phoenix-seller/bill-engine | release-20260818 |
| dolphin-flink-v1 | 1/1 | (仅镜像 · Flink 底座) | — |
| download-front | 1/1 | phoenix-seller-fe/download-front | — |
| jc-lxhb-web | 1/1 | pscc/jc-lxhbz-web | — |
| kaipiao-center | 2/2 | fpgj/kaipiao-center | release-202608018 |
| kaipiao-weapp-h5-new | 1/1 | phoenix-seller-fe/kaipiao-weapp-h5 | release |
| kaipiao-weapp-h5-old | 1/1 | fpgj/kaipiao-weapp-h5 | — |
| mail-ticket-service | 1/1 | phoenix-seller/mail-ticket-service | master |
| n8n-v1 / n8n-worker-v1 | 1/1 ×2 | (第三方 · 非销项业务) | — |
| national-subsidy-billing-mobile | 1/1 | mobile/national-subsidy-billing-mobile | — |
| phoenix-bill | 6/6 | xf-bm-xplat-msg/phoenix-bill | hotfix-20260826 |
| phoenix-bill-consumer | 3/3 | phoenix-seller/athena-elastic-consumer | phoenix-paas |
| phoenix-bill-shard-consumer | 2/2 | phoenix-seller/athena-elastic-consumer | phoenix-paas |
| phoenix-customer-self-ops | 2/2 | phoenix-seller/phoenix-customer-self-ops | master |
| phoenix-dolphin-service | 2/2 | phoenix-seller/phoenix-dolphin-service | master |
| phoenix-file | 4/4 | phoenix-seller/phoenix-file | release-20260818 |
| phoenix-gateway | 2/2 | phoenix-seller/phoenix-gateway | master |
| phoenix-invoice-inventory | 3/3 | phoenix-seller/phoenix-invoice-inventory | release-20260519 |
| phoenix-invoice-master-consumer | 3/3 | phoenix-seller/athena-elastic-consumer | phoenix-paas |
| phoenix-invoice-master-find | 3/3 | phoenix-seller/athena-elastic-consumer | phoenix-find |
| phoenix-invoice-master-find-v2 | 2/2 | phoenix-seller/athena-elastic-consumer | phoenix-find-v2 |
| phoenix-invoice-shard1-consumer | 2/2 | phoenix-seller/athena-elastic-consumer | phoenix-paas |
| phoenix-invoice-shard1-find | 2/2 | phoenix-seller/athena-elastic-consumer | phoenix-find |
| phoenix-invoice-shard1-find-v2 | 2/2 | phoenix-seller/athena-elastic-consumer | phoenix-find-v2 |
| phoenix-invoice-sharing | 4/4 | phoenix-seller/phoenix-invoice-sharing | release-20260317 |
| phoenix-kylie-service1 | 2/2 | pscc/phoenix-kylie-service | master |
| phoenix-kylin-service | 2/2 | phoenix-seller/phoenix-kylin-service | release-20260429 |
| phoenix-migration | 1/1 | phoenix-seller/phoenix-migration | master |
| phoenix-openapi | 2/2 | phoenix-seller/phoenix-openapi | release-20240924 |
| phoenix-red-notification | 2/2 | phoenix-seller/phoenix-red-notification | release-20260818 |
| phoenix-rednotification-consumer | 2/2 | phoenix-seller/athena-elastic-consumer | phoenix-paas |
| phoenix-script-invoice | 1/1 | phoenix-seller/phoenix-script-invoice | release |
| phoenix-seller-adapter | 2/2 | ultraman-app/phoenix-seller-adapter | release-20260818 |
| phoenix-seller-config | 5/5 | xf-bm-xplat-msg/phoenix-seller-config | release-20260818 |
| phoenix-seller-invoice | 6/6 | phoenix-seller/phoenix-seller-invoice | release-20260818 |
| phoenix-seller-open-api | 2/2 | phoenix-seller/phoenix-seller-open-api | release-20260818 |
| phoenix-smart-match-invoice | 2/2 | phoenix-seller/phoenix-smart-match-invoice | release-20260818 |
| phoenix-zhuque-service | 1/1 | phoenix-seller/phoenix-zhuque-service | release |
| receive-invoice-fe | 1/1 | phoenix-seller-fe/receive-invoice-fe | — |
| sales-sso | 1/1 | phoenix-seller-fe/sales-sso | — |
| sourcebill-consumer | 2/2 | phoenix-seller/athena-elastic-consumer | phoenix-source-bill-canal |
| source-bill-service | 2/2 | phoenix-seller/source-bill-service | hotfix-20260826 |
| xck-job-v2-a20a5 | 1/1 | (第三方调度中间件) | — |
| yl-ops-agent-service | 2/2 | phoenix-seller/yl-ops-agent-service | master |
数据快照 2026-09-04;「—」= 无 pod 标签(commit 溯源缺失,其中 7 个已由 tag-fallback 离线还原、4 个为真盲区)。完整字段(含镜像与短 SHA)见 evidence/scope-prod-mapping.csv。
7.3术语与时效声明
术语表
- 销项 / seller——开票(销售方)侧业务,与进项 purchaser 相对;
- 发布列车——以
release-YYYYMMDD命名的批量发布分支约定; - 双向环——A 调 B 且 B 调 A 的两跳循环依赖;
- 四写者表——被 ≥4 个服务同时写入的表(最危险的共享数据);
- 冻→影→切→收——冻结旧库 → 影子同步 → 切换流量 → 收敛下线的迁移四步法;
- tag-fallback——无 pod 标签时用镜像 tag 反推 commit 的溯源回退路径;
- 一仓十役——
athena-elastic-consumer一个仓库在 prod 承载 10 个不同角色负载; - in-situ 轨——对活 pod 在线内省采集的代码/配置事实(区别于静态镜像解析)。
时效与口径声明
- GitLab / K8s / DMS 元数据 / Apollo:快照 2026-09-04(相对报告日滞后 5–7 天);
- 代码归档:2026-09-05;
- 真库活态(L14 直连抽样):2026-09-11;
- in-situ 在线内省轨:停在 2026-07-01(停滞 72 天,凡引用处已单独标注);
- 范围口径:命名空间 ∪ 仓库白名单并集(77 仓);组件口径默认白名单 268 归档,与「严格三组 187」不同处均已标注;
- 容量单位:本报告统一为 二进制 TB(与库表 MB 值一致换算);
- 方案版本:V1.1(经对抗验证修订,修订明细见
03-plan/revision-log.md)。