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

458 lines
11 KiB
Markdown

# FTP 同步工具详细设计
## 1. 文档说明
本文档是对总体方案的继续细化,重点补充以下内容:
- `application.properties` 配置方案
- H2 表结构与初始化方式
- Spring Boot 2.7.18 工程骨架
- 核心类职责划分
- 启动方式与后续待实现事项
## 2. 配置文件策略
本项目采用 `properties` 配置文件,不使用 `yml`
推荐目录如下:
```text
src/main/resources/
|- application.properties
|- application-dev-agent.properties
|- application-prod-agent.properties
|- schema.sql
```
配置分工如下:
- `application.properties`
- 放公共配置
- 包括数据源、H2、通用路径、FTP 默认项、Git 默认项、生产接口默认项
- `application-dev-agent.properties`
- 放开发环境代理专属配置
- 包括开发侧定时任务表达式、开发侧 FTP 账号、Git 仓库分支
- `application-prod-agent.properties`
- 放生产环境代理专属配置
- 包括生产侧定时任务表达式、生产侧 FTP 账号、生产接口地址与认证
## 3. 当前配置项设计
### 3.1 公共配置
已落地文件:
- [application.properties](e:/AIcoding/FtpTool/src/main/resources/application.properties)
核心配置分组如下:
### `spring.*`
- `spring.application.name`
- `spring.datasource.*`
- `spring.jpa.*`
- `spring.sql.init.*`
- `spring.h2.console.*`
用途:
- 启动 Spring Boot
- 使用 H2 文件数据库
- 通过 `schema.sql` 初始化表结构
### `sync.*`
- `sync.node-id`
- `sync.role`
- `sync.work-dir`
- `sync.package-temp-dir`
- `sync.dev-to-prod-staging-dir`
- `sync.prod-to-dev-staging-dir`
- `sync.max-retry-count`
- `sync.ack-scan-batch-size`
用途:
- 标识当前节点身份
- 控制工作目录和临时目录
- 控制同步重试与 ack 扫描参数
### `ftp.*`
- `ftp.host`
- `ftp.port`
- `ftp.username`
- `ftp.password`
- `ftp.passive-mode`
- `ftp.base-dir`
- `ftp.connect-timeout-ms`
- `ftp.data-timeout-ms`
- `ftp.buffer-size`
用途:
- 定义 FTP 连接参数
- 定义远端根目录和超时策略
### `git.repo.*`
- `git.repo.local-path`
- `git.repo.remote-uri`
- `git.repo.username`
- `git.repo.password`
- `git.repo.scan-branch`
- `git.repo.snapshot-branch`
- `git.repo.commit-author-name`
- `git.repo.commit-author-email`
- `git.repo.commit-message-prefix`
- `git.repo.pull-rebase`
用途:
- 定义开发侧 Git 拉取与提交行为
- 指定开发主分支和生产镜像分支
### `prod.api.*`
- `prod.api.base-url`
- `prod.api.push-path`
- `prod.api.pull-path`
- `prod.api.token`
- `prod.api.connect-timeout-ms`
- `prod.api.read-timeout-ms`
用途:
- 定义生产侧 `push/pull` 接口的连接方式
## 4. Profile 设计
### 4.1 开发代理 Profile
已落地文件:
- [application-dev-agent.properties](e:/AIcoding/FtpTool/src/main/resources/application-dev-agent.properties)
主要内容:
- `spring.config.activate.on-profile=dev-agent`
- 开发侧端口
- 开发侧三类任务 cron
- 开发侧 FTP 账号示例
- Git 分支覆盖项
当前定时任务:
- `sync.jobs.dev-git-scan.cron`
- `sync.jobs.dev-consume-prod-package.cron`
- `sync.jobs.dev-ack-scan.cron`
### 4.2 生产代理 Profile
已落地文件:
- [application-prod-agent.properties](e:/AIcoding/FtpTool/src/main/resources/application-prod-agent.properties)
主要内容:
- `spring.config.activate.on-profile=prod-agent`
- 生产侧端口
- 生产侧三类任务 cron
- 生产侧 FTP 账号示例
- 生产接口地址和 token 示例
当前定时任务:
- `sync.jobs.prod-consume-dev-package.cron`
- `sync.jobs.prod-pull-config.cron`
- `sync.jobs.prod-ack-scan.cron`
## 5. H2 设计
已落地文件:
- [schema.sql](e:/AIcoding/FtpTool/src/main/resources/schema.sql)
### 5.1 初始化方式
通过以下配置自动初始化:
```properties
spring.sql.init.mode=always
spring.sql.init.schema-locations=classpath:schema.sql
spring.jpa.hibernate.ddl-auto=none
```
说明:
- 表结构由手工 SQL 控制
- 不依赖 Hibernate 自动建表
- 更适合后续环境迁移和版本管理
### 5.2 已定义表
#### `sync_checkpoint`
用途:
- 保存每个同步方向最后一次成功版本
关键字段:
- `direction`
- `last_success_version`
- `last_success_hash`
- `updated_at`
#### `sync_task`
用途:
- 保存每次同步任务实例
关键字段:
- `trace_id`
- `direction`
- `source_version`
- `content_hash`
- `package_name`
- `status`
- `retry_count`
- `error_msg`
关键约束:
- `trace_id` 唯一
- `direction + source_version + content_hash` 唯一
这组唯一键就是当前骨架里默认采用的幂等键。
#### `sync_ack`
用途:
- 保存跨端 ack 回执
关键字段:
- `trace_id`
- `ack_side`
- `ack_status`
- `ack_time`
- `remark`
## 6. 工程骨架
当前已经在仓库中生成了一套最小 Spring Boot 骨架。
### 6.1 构建文件
- [pom.xml](e:/AIcoding/FtpTool/pom.xml)
已引入的核心依赖:
- `spring-boot-starter`
- `spring-boot-starter-web`
- `spring-boot-starter-data-jpa`
- `spring-boot-starter-actuator`
- `spring-retry`
- `commons-net`
- `org.eclipse.jgit`
- `h2`
### 6.2 启动类
- [FtpSyncToolApplication.java](e:/AIcoding/FtpTool/src/main/java/com/ftptool/sync/FtpSyncToolApplication.java)
作用:
- 启用 Spring Boot
- 启用定时任务
- 启用重试机制
- 注册配置属性类
### 6.3 配置属性类
- [SyncProperties.java](e:/AIcoding/FtpTool/src/main/java/com/ftptool/sync/config/SyncProperties.java)
- [FtpProperties.java](e:/AIcoding/FtpTool/src/main/java/com/ftptool/sync/config/FtpProperties.java)
- [GitRepoProperties.java](e:/AIcoding/FtpTool/src/main/java/com/ftptool/sync/config/GitRepoProperties.java)
- [ProdApiProperties.java](e:/AIcoding/FtpTool/src/main/java/com/ftptool/sync/config/ProdApiProperties.java)
作用:
-`properties` 配置映射为强类型对象
- 避免业务代码直接散落读取字符串 key
### 6.4 基础配置
- [AppConfig.java](e:/AIcoding/FtpTool/src/main/java/com/ftptool/sync/config/AppConfig.java)
当前提供:
- `RestTemplate` Bean
- 读取生产接口超时参数
## 7. 领域模型与仓储
### 7.1 枚举
- [SyncDirection.java](e:/AIcoding/FtpTool/src/main/java/com/ftptool/sync/model/SyncDirection.java)
- [SyncRole.java](e:/AIcoding/FtpTool/src/main/java/com/ftptool/sync/model/SyncRole.java)
- [SyncStatus.java](e:/AIcoding/FtpTool/src/main/java/com/ftptool/sync/model/SyncStatus.java)
用途:
- 统一同步方向、角色和状态定义
### 7.2 实体
- [SyncTask.java](e:/AIcoding/FtpTool/src/main/java/com/ftptool/sync/entity/SyncTask.java)
- [SyncCheckpoint.java](e:/AIcoding/FtpTool/src/main/java/com/ftptool/sync/entity/SyncCheckpoint.java)
- [SyncAck.java](e:/AIcoding/FtpTool/src/main/java/com/ftptool/sync/entity/SyncAck.java)
用途:
- 对应 H2 三张核心业务表
- 内置了基础时间戳维护逻辑
### 7.3 Repository
- [SyncTaskRepository.java](e:/AIcoding/FtpTool/src/main/java/com/ftptool/sync/repository/SyncTaskRepository.java)
- [SyncCheckpointRepository.java](e:/AIcoding/FtpTool/src/main/java/com/ftptool/sync/repository/SyncCheckpointRepository.java)
- [SyncAckRepository.java](e:/AIcoding/FtpTool/src/main/java/com/ftptool/sync/repository/SyncAckRepository.java)
用途:
- 提供基础持久化能力
- 已包含按幂等键和 `traceId` 查询的方法
## 8. 当前服务层设计
### 8.1 已实现基础服务
- [SyncTaskService.java](e:/AIcoding/FtpTool/src/main/java/com/ftptool/sync/service/SyncTaskService.java)
- [CheckpointService.java](e:/AIcoding/FtpTool/src/main/java/com/ftptool/sync/service/CheckpointService.java)
- [AckService.java](e:/AIcoding/FtpTool/src/main/java/com/ftptool/sync/service/AckService.java)
当前能力:
- 创建或加载幂等任务
- 更新任务状态
- 增加重试次数
- 更新检查点
- 记录 ack 回执
### 8.2 当前未实现的业务服务
当前骨架还没有把以下真实能力写完:
- FTP 上传、下载、列目录、重命名
- Git clone / pull / checkout / commit / push
- zip 打包与解包
- manifest 生成与校验
- 生产 `push` / `pull` 接口调用
这些是下一步真正要补的业务实现层。
## 9. 当前调度层设计
### 9.1 开发侧调度
- [DevSyncCoordinator.java](e:/AIcoding/FtpTool/src/main/java/com/ftptool/sync/orchestrator/DevSyncCoordinator.java)
- [DevGitScanJob.java](e:/AIcoding/FtpTool/src/main/java/com/ftptool/sync/job/DevGitScanJob.java)
- [DevConsumeProdPackageJob.java](e:/AIcoding/FtpTool/src/main/java/com/ftptool/sync/job/DevConsumeProdPackageJob.java)
- [DevAckScanJob.java](e:/AIcoding/FtpTool/src/main/java/com/ftptool/sync/job/DevAckScanJob.java)
当前状态:
- 已按 `dev-agent` profile 进行隔离
- 已绑定 cron 表达式
- 当前仅输出清晰日志和待办动作
### 9.2 生产侧调度
- [ProdSyncCoordinator.java](e:/AIcoding/FtpTool/src/main/java/com/ftptool/sync/orchestrator/ProdSyncCoordinator.java)
- [ProdConsumeDevPackageJob.java](e:/AIcoding/FtpTool/src/main/java/com/ftptool/sync/job/ProdConsumeDevPackageJob.java)
- [ProdPullConfigJob.java](e:/AIcoding/FtpTool/src/main/java/com/ftptool/sync/job/ProdPullConfigJob.java)
- [ProdAckScanJob.java](e:/AIcoding/FtpTool/src/main/java/com/ftptool/sync/job/ProdAckScanJob.java)
当前状态:
- 已按 `prod-agent` profile 进行隔离
- 已绑定 cron 表达式
- 当前仅输出清晰日志和待办动作
## 10. 当前目录结构
```text
FtpTool
|- docs
|- pom.xml
|- src
|- main
|- java/com/ftptool/sync
| |- config
| |- entity
| |- job
| |- model
| |- orchestrator
| |- repository
| |- service
|- resources
|- application.properties
|- application-dev-agent.properties
|- application-prod-agent.properties
|- schema.sql
```
## 11. 启动方式
### 11.1 启动开发代理
```bash
mvn spring-boot:run -Dspring-boot.run.profiles=dev-agent
```
### 11.2 启动生产代理
```bash
mvn spring-boot:run -Dspring-boot.run.profiles=prod-agent
```
也可以打包后通过 JVM 参数指定:
```bash
java -jar ftp-sync-tool.jar --spring.profiles.active=dev-agent
java -jar ftp-sync-tool.jar --spring.profiles.active=prod-agent
```
## 12. 下一步建议实现顺序
建议按以下顺序继续落代码:
1. 先实现 `FtpClientService`
2. 再实现 `GitClientService`
3. 再实现 `PackageService`
4. 再实现 `ProdConfigApiService`
5. 最后把 `Coordinator` 中的 TODO 串起来
## 13. 当前边界
当前骨架是“可扩展的项目起点”,不是完整业务实现,现阶段还缺:
- 真正的 FTP 交互
- 真正的 Git 操作
- 真正的生产接口调用
- 包文件读写与校验
- ack 文件协议
- 失败重试细节和告警
但好处是结构已经固定住了:
- 配置口径统一为 `properties`
- profile 隔离清晰
- H2 状态表已定义
- 调度入口已分开
- 任务、检查点、ack 的存储模型已落地