FtpTool/docs/ftp-sync-tool-detail-design.md
2026-04-28 17:00:58 +08:00

282 lines
7.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Git 直连架构详细设计
## 1. 文档说明
本文档描述当前实现层面的详细设计,重点覆盖:
- Git 版本分支和目录结构约定
- `Git -> PROD` 的增量与参数映射逻辑
- `PROD -> Git` 的落盘与回写逻辑
- 运行配置、工作目录和已知限制
## 2. 当前推荐部署
当前推荐只部署:
- `prod-agent`
运行要求:
- 能访问开发 Git
- 能向 Git 推送 `snapshotBranch`
- 能访问生产 `push/pull/login` 接口
- 能写本地 H2 文件数据库
## 3. 配置文件策略
当前使用:
```text
src/main/resources/
|- application.properties
|- application-prod-agent.properties
|- schema.sql
```
说明:
- `application.properties` 提供公共默认值
- `application-prod-agent.properties` 提供生产侧 profile 配置
## 4. 核心配置口径
### 4.1 Git 配置
| 配置项 | 说明 |
| --- | --- |
| `git.repo.remote-uri` | Git 远端地址 |
| `git.repo.username` | Git 用户名 |
| `git.repo.password` | Git 密码或 token |
| `git.repo.scan-branch` | 当前待同步的单个版本分支名 |
| `git.repo.scan-branch-pattern` | 批量扫描的版本分支匹配规则 |
| `git.repo.snapshot-branch` | 动态生产快照分支前缀 |
| `git.repo.commit-message-prefix` | PROD -> Git 提交前缀 |
### 4.2 生产接口配置
| 配置项 | 说明 |
| --- | --- |
| `prod.api.base-url` | 生产接口基础地址 |
| `prod.api.push-path` | `pushConfig` 路径 |
| `prod.api.pull-path` | `pullConfig` 路径 |
| `prod.api.login-path` | `login` 路径 |
| `prod.api.token` | 静态 token可选 |
| `prod.api.token-header-name` | token 请求头名称 |
| `prod.api.airport-id` | `pullConfig` 可选过滤 |
| `prod.api.app-name` | `pullConfig` 可选过滤 |
| `prod.api.pull-config-version` | `pullConfig` 可选版本过滤 |
| `prod.api.pull-file-name` | `pullConfig` 可选文件过滤 |
说明:
- `prod.api.airport-id``prod.api.app-name` 当前只用于 `pullConfig` 的可选过滤
- 它们已经不再用于 Git -> PROD 参数解析
### 4.3 调度配置
当前生产侧调度:
- `sync.jobs.prod-git-to-prod.cron`
- `sync.jobs.prod-to-git.cron`
## 5. Git 仓库约定
### 5.1 版本分支
当前实现约定:
- Git -> PROD 支持两种入口:
- `git.repo.scan-branch`:单分支定向同步
- `git.repo.scan-branch-pattern`:批量枚举版本分支
- **分支名本身就是 `configVersion`**
例如:
- `R_XXX_V3.0.3_XXX`
### 5.2 分支内目录结构
当前分支内目录必须为:
```text
<airportId>/<appName>/<模块内文件相对路径>
```
示例:
```text
R_XXX_V3.0.3_XXX
├─ PEK
│ └─ monitor
│ ├─ application.yml
│ └─ jobs/sync-job.json
└─ SHA
└─ gate
└─ gate-rule.json
```
### 5.3 路径校验
当前实现要求每个待推送文件都至少有 3 段路径:
```text
airportId / appName / fileName
```
否则直接视为非法仓库结构并终止同步。
## 6. 工作目录设计
当前工作目录:
```text
work/
├─ package/
├─ staging/
│ ├─ dev-to-prod/
│ └─ prod-to-dev/
└─ baseline/
└─ git-to-prod/
└─ <scan-branch>/
```
说明:
- `dev-to-prod/`:保存导出的 Git 版本快照与增量目录
- `prod-to-dev/`:保存 `pullConfig` 恢复出的临时目录
- `baseline/git-to-prod/<scan-branch>/`:保存某个版本分支上次成功下发后的基线
## 7. Git -> PROD 详细流程
### 7.1 流程步骤
1. 解析单分支或批量匹配规则
2. 逐个拉取命中的版本分支
3. 读取当前 `HEAD revision`
4. 以分支名作为 `sourceVersion`
5. 导出分支工作树到 staging 目录
6. 计算目录内容哈希
7.`direction + sourceVersion + contentHash` 做幂等判断
8. 计算本次推送目录:
- 首次全量
- 删除回退全量
- 其余场景最小增量
9. 遍历目录内所有文件,按路径解析出 `airportId/appName/fileName`
10. 组装 `pushConfig` JSON 数组并提交
11. 成功后刷新 checkpoint、task 和 baseline
### 7.2 参数映射规则
| Git 信息 | pushConfig 字段 |
| --- | --- |
| `scan-branch` | `configVersion` |
| 路径第 1 段 | `airportId` |
| 路径第 2 段 | `appName` |
| 第 3 段及之后 | `fileName` |
| 文件 UTF-8 内容 | `configContent` |
### 7.3 当前实现说明
- `HEAD revision` 仅用于日志和 staging 目录名
- 不再用 `commit SHA` 作为对外业务版本号
- `configContent` 目前仍是明文
## 8. PROD -> Git 详细流程
### 8.1 流程步骤
1. 调用 `pullConfig`
2. 可选附带 `airportId/appName` 过滤
3. 自动附带本地待回传的 `ackSuc/ackFail`
4. 解析响应项
5.`airportId/appName/fileName` 落盘到 staging 目录
6. 计算内容哈希和来源版本
7. 按幂等键判断是否已处理
8. 提交到 `git.repo.snapshot-branch/<configVersion>`
9. 成功后更新 checkpoint、task 和本地 ACK 状态
### 8.2 来源版本规则
当前实现:
- 如果本次 `pullConfig` 返回项里的 `configVersion` 全部一致,则该值作为 `sourceVersion`
- 如果返回多种不同 `configVersion`,则退回为内容哈希
### 8.3 动态快照分支规则
- 每个 `ProdPullResult` 都会写入独立目标分支:
```text
git.repo.snapshot-branch/<sourceVersion>
```
-`sourceVersion` 就是接口返回的统一 `configVersion` 时,目标分支即按版本动态展开
- 当某组缺少版本号时,会退回为基于内容哈希的 `sourceVersion`
## 9. 当前接口协议实现口径
### 9.1 pushConfig
- 方法:`POST`
- 载荷:`JSON 数组`
- 每个文件一条记录
- `ackFail` 非空时本次同步直接失败
- `configContent` 已统一通过 `ConfigCryptoService` 处理,当前默认实现仍为透传
### 9.2 pullConfig
- 方法:`GET`
- 参数query string
- 当前已支持:
- `airportId`
- `appName`
- `ackSuc`
- `ackFail`
- 当前已支持:
- `configVersion`
- `fileName`
- 对于本地处理失败的 `ackFail` 项,当前会持久化重试上下文,并在下一个周期按 `airportId/appName/configVersion/fileName` 定向重拉
### 9.3 login
- 方法:`POST`
- 如果未配置静态 token则自动调用
- token 会按 `expireTime` 缓存
## 10. 状态表设计
当前主表:
- `sync_checkpoint`
- `sync_task`
- `prod_pull_ack`
作用:
- `sync_checkpoint`:方向级最后成功版本和哈希
- `sync_task`:任务状态、重试次数、错误摘要
- `prod_pull_ack`:待回传给生产侧的 ACK 状态
## 11. 当前已实现能力
- Git -> PROD 主链路已可用
- PROD -> Git 主链路已可用
- `pushConfig`/`pullConfig`/`login` 已适配正式协议
- `ackSuc/ackFail` 已接入回传与本地落库
- Git -> PROD 已支持最小增量推送
- 管理接口已提供最近任务、失败任务和检查点视图
## 12. 当前主要 TODO
-`ConfigCryptoService` 的透传实现替换为正式加解密算法
## 13. 结论
当前详细设计已经不再是“固定主分支 + 全局机场配置”的口径,而是:
- 版本靠分支表达
- 机场和模块靠目录表达
- 路径直接决定接口参数
后续再扩展功能时,应在这个模型上继续演进。