# 基于 Git 版本分支的配置双向同步工具设计方案 ## 1. 文档目的 本文档说明当前 Git 直连同步工具的目标模型、仓库约定和双向同步流程。 适用范围: - 生产环境定时从开发 Git 拉取某个版本分支,并调用生产 `pushConfig` 下发配置 - 生产环境定时从生产 `pullConfig` 拉取当前配置,并回写到 Git 快照分支 - FTP 已退出主运行面 ## 2. 核心约束 ### 2.1 技术约束 - JDK:`1.8` - Spring Boot:`2.7.18` - 状态库:`H2` - Git 操作:`JGit` ### 2.2 网络与部署约束 - 生产环境可以读取开发 Git - 生产环境需要能向 Git 推送快照分支 - 生产环境需要能访问生产 `push/pull/login` 接口 - FTP 不再参与同步流程 ## 3. 总体架构 推荐拓扑: ```text 开发 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 分支内目录约定 每个版本分支内部必须按以下结构组织: ```text //<模块内文件相对路径> ``` 示例: ```text 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` 会把拉回的数据提交到: ```text git.repo.snapshot-branch/ ``` 目录结构同样为: ```text // ``` ## 5. 两条核心链路 ### 5.1 Git -> PROD 目标: - 将当前版本分支中的配置同步到生产 流程: 1. 拉取 `git.repo.scan-branch` 2. 读取当前 `HEAD revision` 3. 以 **分支名** 作为业务版本号 `sourceVersion` 4. 导出该分支工作树 5. 解析所有 `airportId/appName/fileName` 配置项 6. 调用生产 `pushConfig` 7. 成功后更新 `sync_task` 和 `sync_checkpoint` 说明: - `revision` 仅用于日志和 staging 目录隔离 - 当前不再使用 `commit SHA` 作为下发版本号 ### 5.2 PROD -> Git 目标: - 将生产当前配置快照回写到 Git 流程: 1. 调用生产 `pullConfig` 2. 把返回项落盘为 `airportId/appName/fileName` 3. 计算内容哈希和来源版本 4. 提交到 `git.repo.snapshot-branch/` 5. 成功后更新 `sync_task` 和 `sync_checkpoint` ## 6. 接口参数与路径映射 Git -> PROD 时,每个文件都映射为一条 `pushConfig` 记录: | Git 信息 | 接口字段 | | --- | --- | | 分支名 | `configVersion` | | 路径第 1 段 | `airportId` | | 路径第 2 段 | `appName` | | 路径第 3 段及之后 | `fileName` | | 文件内容 | `configContent` | 例如: ```text PEK/monitor/jobs/sync-job.json ``` 会变成: ```json { "airportId": "PEK", "appName": "monitor", "configVersion": "R_XXX_V3.0.3_XXX", "fileName": "jobs/sync-job.json" } ``` ## 7. 增量策略 当前 Git -> PROD 已实现: - 首次同步全量 - 后续优先按文件哈希做最小增量 - 检测到删除时自动回退为全量 并且 baseline 已按版本分支隔离: ```text work/baseline/git-to-prod// ``` 避免不同版本分支之间相互污染。 ## 8. 状态设计 当前状态表: - `sync_checkpoint` - `sync_task` - `prod_pull_ack` 说明: - `sync_checkpoint`:记录某方向最后一次成功版本和哈希 - `sync_task`:记录每次同步任务和重试状态 - `prod_pull_ack`:记录 `pullConfig` 的 `ackSuc/ackFail` 回传状态 ## 9. 幂等设计 当前幂等键: ```text direction + sourceVersion + contentHash ``` 作用: - 同一版本分支下同一内容不会重复推送 - 同一生产快照不会重复回写 Git ## 10. 当前配置口径 关键 Git 配置: ```properties 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) ``` 关键接口配置: ```properties 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-id`、`prod.api.app-name` 当前只作为 `pullConfig` 可选过滤参数 - 它们不再承担 Git -> PROD 的参数组装职责 - `prod.api.pull-config-version`、`prod.api.pull-file-name` 可用于进一步缩小 `pullConfig` 拉取范围 ## 11. 当前已实现能力 - `pushConfig`:`POST + JSON 数组` - `pullConfig`:`GET + 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/` 动态分支写回**