FtpTool/docs/ftp-sync-tool-design.md
dark 114bcf33d8 feat: 同步链路支持版本分支目录映射、动态快照分支和 ackFail 定向重拉
- Git -> PROD 改为按 branch 作为 configVersion
- 按 airportId/appName/fileName 目录结构解析 pushConfig 参数
- PROD -> Git 改为写入 snapshot-branch/<configVersion> 动态分支
- pullConfig 支持 configVersion/fileName 可选过滤
- 抽出 ConfigCryptoService,统一收口加解密扩展点
- ackFail 落库增加重试上下文,支持按 airportId/appName/configVersion/fileName 定向重拉
- 同步更新测试、接口文档和 current.md
2026-04-28 14:49:33 +08:00

5.6 KiB
Raw Blame History

基于 Git 版本分支的配置双向同步工具设计方案

1. 文档目的

本文档说明当前 Git 直连同步工具的目标模型、仓库约定和双向同步流程。

适用范围:

  • 生产环境定时从开发 Git 拉取某个版本分支,并调用生产 pushConfig 下发配置
  • 生产环境定时从生产 pullConfig 拉取当前配置,并回写到 Git 快照分支
  • FTP 已退出主运行面

2. 核心约束

2.1 技术约束

  • JDK1.8
  • Spring Boot2.7.18
  • 状态库:H2
  • Git 操作:JGit

2.2 网络与部署约束

  • 生产环境可以读取开发 Git
  • 生产环境需要能向 Git 推送快照分支
  • 生产环境需要能访问生产 push/pull/login 接口
  • FTP 不再参与同步流程

3. 总体架构

推荐拓扑:

开发 Git 仓库 <----> 生产环境 prod-agent <----> 生产系统 push/pull 接口

当前只保留一个正式运行角色:

  • prod-agent

4. Git 仓库约定

4.1 版本分支约定

当前需求下:

  • 一个待发布版本对应一个 Git 分支
  • git.repo.scan-branch 直接配置为当前待同步版本分支
  • 分支名本身就是 configVersion

示例:

  • R_XXX_V3.0.3_XXX
  • R_XXX_V3.0.4_XXX

4.2 分支内目录约定

每个版本分支内部必须按以下结构组织:

<airportId>/<appName>/<模块内文件相对路径>

示例:

R_XXX_V3.0.3_XXX
├─ PEK
│  └─ monitor
│     ├─ application.yml
│     └─ jobs/sync-job.json
└─ SHA
   └─ gate
      └─ gate-rule.json

4.3 快照分支约定

当前实现使用动态快照分支:

  • git.repo.snapshot-branch=config-prod-snapshot

PROD -> Git 会把拉回的数据提交到:

git.repo.snapshot-branch/<configVersion>

目录结构同样为:

<airportId>/<appName>/<fileName>

5. 两条核心链路

5.1 Git -> PROD

目标:

  • 将当前版本分支中的配置同步到生产

流程:

  1. 拉取 git.repo.scan-branch
  2. 读取当前 HEAD revision
  3. 分支名 作为业务版本号 sourceVersion
  4. 导出该分支工作树
  5. 解析所有 airportId/appName/fileName 配置项
  6. 调用生产 pushConfig
  7. 成功后更新 sync_tasksync_checkpoint

说明:

  • revision 仅用于日志和 staging 目录隔离
  • 当前不再使用 commit SHA 作为下发版本号

5.2 PROD -> Git

目标:

  • 将生产当前配置快照回写到 Git

流程:

  1. 调用生产 pullConfig
  2. 把返回项落盘为 airportId/appName/fileName
  3. 计算内容哈希和来源版本
  4. 提交到 git.repo.snapshot-branch/<configVersion>
  5. 成功后更新 sync_tasksync_checkpoint

6. 接口参数与路径映射

Git -> PROD 时,每个文件都映射为一条 pushConfig 记录:

Git 信息 接口字段
分支名 configVersion
路径第 1 段 airportId
路径第 2 段 appName
路径第 3 段及之后 fileName
文件内容 configContent

例如:

PEK/monitor/jobs/sync-job.json

会变成:

{
  "airportId": "PEK",
  "appName": "monitor",
  "configVersion": "R_XXX_V3.0.3_XXX",
  "fileName": "jobs/sync-job.json"
}

7. 增量策略

当前 Git -> PROD 已实现:

  • 首次同步全量
  • 后续优先按文件哈希做最小增量
  • 检测到删除时自动回退为全量

并且 baseline 已按版本分支隔离:

work/baseline/git-to-prod/<scan-branch>/

避免不同版本分支之间相互污染。

8. 状态设计

当前状态表:

  • sync_checkpoint
  • sync_task
  • prod_pull_ack

说明:

  • sync_checkpoint:记录某方向最后一次成功版本和哈希
  • sync_task:记录每次同步任务和重试状态
  • prod_pull_ack:记录 pullConfigackSuc/ackFail 回传状态

9. 幂等设计

当前幂等键:

direction + sourceVersion + contentHash

作用:

  • 同一版本分支下同一内容不会重复推送
  • 同一生产快照不会重复回写 Git

10. 当前配置口径

关键 Git 配置:

git.repo.scan-branch=R_XXX_V3.0.3_XXX
git.repo.snapshot-branch=config-prod-snapshot
git.repo.commit-message-prefix=sync(prod->git)

关键接口配置:

prod.api.base-url=https://prod.example.com
prod.api.push-path=/pic_bus_manage_monitor/configSync/pushConfig
prod.api.pull-path=/pic_bus_manage_monitor/configSync/pullConfig
prod.api.login-path=/pic_bus_manage_monitor/pam-monitor/login
prod.api.token=replace-me
prod.api.token-header-name=token
prod.api.airport-id=
prod.api.app-name=
prod.api.pull-config-version=
prod.api.pull-file-name=

说明:

  • prod.api.airport-idprod.api.app-name 当前只作为 pullConfig 可选过滤参数
  • 它们不再承担 Git -> PROD 的参数组装职责
  • prod.api.pull-config-versionprod.api.pull-file-name 可用于进一步缩小 pullConfig 拉取范围

11. 当前已实现能力

  • pushConfigPOST + JSON 数组
  • pullConfigGET + JSON 响应
  • login:自动获取并缓存 token
  • ackSuc/ackFail:已接入请求回传与本地落库
  • Git -> PROD已支持最小增量推送
  • 管理接口:
    • GET /api/admin/sync/overview
    • GET /api/admin/sync/tasks/recent
    • GET /api/admin/sync/tasks/failed

12. 当前未完成项

  • ConfigCryptoService 的透传实现替换为正式加解密算法

13. 结论

当前文档口径应统一为:

  • 版本用 Git 分支表达
  • 机场和模块用目录表达
  • 接口参数由路径直接解析
  • 快照按 git.repo.snapshot-branch/<configVersion> 动态分支写回