282 lines
7.0 KiB
Markdown
282 lines
7.0 KiB
Markdown
# 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. 结论
|
||
|
||
当前详细设计已经不再是“固定主分支 + 全局机场配置”的口径,而是:
|
||
|
||
- 版本靠分支表达
|
||
- 机场和模块靠目录表达
|
||
- 路径直接决定接口参数
|
||
|
||
后续再扩展功能时,应在这个模型上继续演进。
|