From 14a8cc6a999c4905b454b7bb3a7beabf5f457b4a Mon Sep 17 00:00:00 2001 From: dark Date: Tue, 28 Apr 2026 15:55:38 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E8=A1=A5=E5=85=85=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application-prod-agent.properties | 16 ++++++- src/main/resources/application.properties | 42 ++++++++++++++++--- src/main/resources/schema.sql | 30 +++++++++++++ 3 files changed, 80 insertions(+), 8 deletions(-) diff --git a/src/main/resources/application-prod-agent.properties b/src/main/resources/application-prod-agent.properties index 830f3ec..a266d0d 100644 --- a/src/main/resources/application-prod-agent.properties +++ b/src/main/resources/application-prod-agent.properties @@ -1,23 +1,35 @@ +# prod-agent 专属 profile spring.config.activate.on-profile=prod-agent server.port=8082 +# 当前正式运行节点标识与角色 sync.node-id=prod-agent-01 sync.role=PROD -# PROD side directly pulls Git and synchronizes with production APIs +# 生产侧直接拉取 Git 并调用生产接口完成双向同步 +# Git -> PROD 每分钟执行一次 sync.jobs.prod-git-to-prod.cron=0 */1 * * * * +# PROD -> Git 每两分钟执行一次,错开 20 秒避免和上面的任务完全重叠 sync.jobs.prod-to-git.cron=20 */2 * * * * -# Example overrides +# 生产接口覆盖示例 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 + +# 注意:这里必须替换成真实 token 或改成 replace-me。 +# 如果保留 change-me,程序会把它当成真实 token 使用,而不会自动走 login。 prod.api.token=change-me prod.api.token-header-name=token + +# pullConfig 的可选过滤条件。 +# 留空或 replace-me 时,不会带入请求。 prod.api.airport-id=replace-me prod.api.app-name=replace-me prod.api.pull-config-version= prod.api.pull-file-name= + +# login 接口凭证。 prod.api.login-name= prod.api.login-password= diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 1abdcae..76cecbf 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,9 +1,10 @@ -# Common application settings +# 应用基础配置 spring.application.name=git-direct-sync-tool server.port=8080 spring.main.banner-mode=off -# H2 file mode to persist checkpoints and retry state +# H2 文件库。 +# 用于持久化同步检查点、任务状态和 ACK 重试元数据。 spring.datasource.url=jdbc:h2:file:./data/git-direct-sync-tool-db;AUTO_SERVER=TRUE;MODE=MYSQL spring.datasource.driver-class-name=org.h2.Driver spring.datasource.username=sa @@ -16,44 +17,73 @@ spring.sql.init.schema-locations=classpath:schema.sql spring.h2.console.enabled=true spring.h2.console.path=/h2-console +# 当前仅暴露基础健康检查和信息接口。 management.endpoints.web.exposure.include=health,info -# Common sync settings +# 同步运行公共配置 +# node-id 主要用于日志定位;role 会被具体 profile 覆盖。 sync.node-id=default-node sync.role=UNSET + +# 本地工作目录。 +# staging/baseline/package 等运行期目录都会从这里派生。 sync.work-dir=./work sync.package-temp-dir=./work/package sync.dev-to-prod-staging-dir=./work/staging/dev-to-prod sync.prod-to-dev-staging-dir=./work/staging/prod-to-dev + +# 同步任务最大自动重试次数。 sync.max-retry-count=5 + +# pullConfig 返回项缺少 fileName 时使用的兜底文件名。 sync.pull-response-file-name=prod-config.json -# Git defaults +# Git 默认配置 git.repo.local-path=./work/git/config-repo git.repo.remote-uri=https://git.example.com/config.git git.repo.username=replace-me git.repo.password=replace-me + +# 当前待同步的版本分支。 +# 当前业务约定:分支名本身就是 configVersion。 git.repo.scan-branch=R_XXX_V3.0.3_XXX + +# 生产快照分支前缀。 +# PROD -> Git 实际回写目标为:snapshot-branch/ git.repo.snapshot-branch=config-prod-snapshot + +# 生产快照回写 Git 时使用的提交身份和提交信息前缀。 git.repo.commit-author-name=git-sync-bot git.repo.commit-author-email=git-sync-bot@example.com git.repo.commit-message-prefix=sync(prod->git) git.repo.pull-rebase=false -# Production API defaults +# 生产接口默认配置 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 + +# 静态 token。 +# replace-me 表示未配置,运行时会自动走 login 接口取 token。 prod.api.token=replace-me prod.api.token-header-name=token + +# pullConfig 可选过滤条件。 +# 这两个字段不再参与 pushConfig 参数组装,只影响拉取范围。 prod.api.airport-id=replace-me prod.api.app-name=replace-me + +# pullConfig 的精细过滤条件,可按版本或单文件定向拉取。 prod.api.pull-config-version= prod.api.pull-file-name= + +# login 接口凭证。 prod.api.login-name= prod.api.login-password= + +# HTTP 超时配置,单位毫秒。 prod.api.connect-timeout-ms=10000 prod.api.read-timeout-ms=30000 -# Keep profile specific cron expressions in application-.properties +# 定时任务 cron 放在 application-.properties 中按角色覆盖。 diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql index e76c626..1f2825d 100644 --- a/src/main/resources/schema.sql +++ b/src/main/resources/schema.sql @@ -1,48 +1,78 @@ +-- 同步检查点表。 +-- 每个同步方向只保留一条最后成功记录。 create table if not exists sync_checkpoint ( id bigint generated by default as identity primary key, + -- 同步方向:DEV_TO_PROD / PROD_TO_DEV direction varchar(32) not null, + -- 最后一次成功版本号 last_success_version varchar(128), + -- 最后一次成功内容哈希 last_success_hash varchar(128), + -- 最近更新时间 updated_at timestamp not null, constraint uk_sync_checkpoint_direction unique (direction) ); +-- 同步任务表。 +-- 记录每一次 Git -> PROD 或 PROD -> Git 的执行状态。 create table if not exists sync_task ( id bigint generated by default as identity primary key, + -- 任务追踪号 trace_id varchar(64) not null, + -- 同步方向 direction varchar(32) not null, + -- 来源版本号,当前通常是版本分支名或生产快照分组版本 source_version varchar(128) not null, + -- 任务对应的内容哈希 content_hash varchar(128) not null, + -- 历史保留字段,当前可为空 package_name varchar(255), + -- 任务状态 status varchar(32) not null, + -- 任务级自动重试次数 retry_count int not null default 0, + -- 最近错误摘要 error_msg clob, created_at timestamp not null, updated_at timestamp not null, constraint uk_sync_task_trace unique (trace_id), + -- 业务幂等键 constraint uk_sync_task_business unique (direction, source_version, content_hash) ); create index if not exists idx_sync_task_status on sync_task (status); create index if not exists idx_sync_task_direction on sync_task (direction); +-- pullConfig ACK 表。 +-- 除了记录 ackSuc/ackFail 回传状态外,还保存失败项定向重拉所需上下文。 create table if not exists prod_pull_ack ( id bigint generated by default as identity primary key, + -- 生产端返回的配置项唯一 id remote_config_id varchar(128) not null, + -- ACK 状态:SUCCESS / FAILED ack_status varchar(16) not null, + -- 是否已经在后续 pullConfig 请求中成功回传 reported boolean not null default false, + -- 失败项来源版本,用于定向重拉 source_version varchar(128), + -- 失败项机场 airport_id varchar(128), + -- 失败项模块 app_name varchar(128), + -- 失败项模块内文件路径 file_name varchar(512), + -- ACK 定向重拉次数 retry_count int not null default 0, + -- 下一次允许重拉的时间点 next_retry_at timestamp, + -- 最近一次失败摘要 last_error_msg clob, created_at timestamp not null, updated_at timestamp not null, constraint uk_prod_pull_ack_remote_id unique (remote_config_id) ); +-- 兼容已经存在的旧库,增量补齐 ACK 重试相关字段。 alter table prod_pull_ack add column if not exists source_version varchar(128); alter table prod_pull_ack add column if not exists airport_id varchar(128); alter table prod_pull_ack add column if not exists app_name varchar(128);