English | 中文
高可靠的分布式批处理调度与执行平台:把「文件接收 → 解析 → 校验 → 装载 → 分发」这条链路做成多租户、可编排、可续跑、可观测的工程化服务,而不是散落在各业务系统里的定时脚本。
File Batch System(BFS)是一套自托管的分布式批处理平台,面向金融、结算、数据传输等对可靠性要求高的批处理场景:
- 上游把文件或事件交给平台,平台负责按计划触发、编排依赖、分片路由、执行并回报结果;
- 内置 import / export / process / dispatch 四类文件/数据流水线,以及独立 atomic Worker 承载 shell / SQL / 存储过程 / HTTP 原子任务;
- 核心保证:任务状态与消息发送同事务(Outbox)、执行前先 CLAIM 防重复、失败可断点续跑、全程可观测可审计;
- 多租户共享集群:按
tenant_id隔离数据、SLA、配额与权限。
| 常见做法 | 痛点 | BFS 的做法 |
|---|---|---|
| 各业务系统自己写定时脚本 | 无统一监控、重试、审计,出问题靠人盯 | 统一任务定义 + 控制台 + 观测栈 |
| 单机批处理框架(如 Spring Batch) | 单点部署、无多租户、无分布式调度 | Orchestrator 唯一状态主机 + Worker 集群,多节点扩展 |
| 任务先落库、再发消息 | 消息丢失 / 重复导致任务状态不一致 | Outbox 事务性发件箱,业务状态与消息强一致 |
| 失败后整批重跑 | 百万行文件重跑成本高、SLA 受损 | 逐行错误追踪 + 阶段级 checkpoint 断点续跑 |
| 租户共用集群互相影响 | 资源争抢、数据越权 | tenant_id 全链路隔离 + Fair-share 配额 + 突发借用 |
| 流程有先后、分支依赖 | 编排逻辑固化在业务代码里 | DAG 工作流:条件分支 + 并行执行 |
- Outbox 保证投递:任务状态写入与消息发布在同一事务内,消除消息丢失风险
- DAG 工作流编排:支持多节点有向无环图调度,含条件分支与并行执行
- 断点续跑(Checkpoint):导入 LOAD / 导出 GENERATE 等阶段持久化续跑位点,崩溃后从断点继续而非全量重跑
- 资源配额管理:Fair-share 调度、突发借用(Burst)、滑动窗口重置
- Worker 优雅排空:ONLINE → DRAINING → DECOMMISSIONED 生命周期管理
- 补偿与重试:内置重试策略(FIXED / EXPONENTIAL / NONE)和审批补偿链路
- 文件错误追踪:逐行记录解析/校验/加载失败,支持跳过与审计
- dry-run 演练:批量日 / 配置包 / 五类 Worker 支持无副作用预检,用于上线前容量、幂等和配置正确性验证
- 配置治理:配置项按
STATIC/DYNAMIC_DB/SECRET/RESTART_REQUIRED标记,Console、Helm checksum、CI 守护共同防止配置漂移 - 租户自托管 SDK:Java / Python / Go / TypeScript / Rust 五种语言 SDK,租户可在自有环境注册 Worker(ADR-035,详见下方)
一条任务的生命周期:
flowchart LR
S[外部文件 / 业务事件] --> T[batch-trigger<br/>Quartz 集群调度]
T --> O[batch-orchestrator<br/>DAG 编排 · 分片 · 路由]
O -->|Outbox 同事务| DB[(PostgreSQL<br/>唯一事实来源)]
O -->|Kafka 异步驱动| W[batch-worker 集群<br/>CLAIM → EXECUTE → REPORT]
W --> DB
W --> X[S3 兼容对象存储 / SFTP / 目标系统]
O <--> C[batch-console-api<br/>控制台 · 审计 · AI 辅助]
五类 Worker:
| Worker | 定位 | 阶段 / 执行模型 | |---|---| | import | 文件接收、解析、校验、装载 | RECEIVE → PREPROCESS → PARSE → VALIDATE → LOAD → FEEDBACK | | export | 查询、渲染、分片导出、对象存储落地 | PREPARE → GENERATE → STORE → REGISTER → COMPLETE | | process | staging、计算/聚合、校验、commit、幂等重跑 | READ → TRANSFORM → STAGE → PUBLISH → FEEDBACK | | dispatch | SFTP / NAS / HTTP / S3 等下游交付 | PREPARE → DISPATCH → ACK → RETRY/COMPENSATE → COMPLETE | | atomic | 受控 shell / SQL / stored-proc / HTTP 原子任务 | 无文件 pipeline,独立隔离执行器,遵守 allowlist / timeout / RCE 边界 |
更详细的状态主链与关键约束见架构约束;端到端流程图见 docs/architecture/system-flow-overview.md。
租户可以在自己的进程 / 机房 / K8s / VM 里运行业务 handler,只通过 HTTP(/internal/*)+ Kafka 与平台通信——不连平台数据库、不加载平台代码、数据 0 出域。平台只承担调度面:register → 派单 → claim → execute → report。
| 语言 | 坐标 / 包名 | 说明 |
|---|---|---|
| Java | io.github.pinpols.batch:batch-worker-sdk |
零 Spring 依赖的 core;可选 -spring-boot-starter 适配层(Boot 4.x) |
| Python | batch-worker-sdk(import batch_worker_sdk) |
3.12+,async-only,pydantic v2 / httpx / aiokafka |
| Go / TypeScript / Rust | 见 sdk/README.md | 与 Java/Python 共用同一套契约 fixture 跨语言验证 |
接入与运维:
- 5 分钟快速开始
- 从 0 到生产的接入旅程
- 租户 worker 上线运维(API key / Kafka SASL / task type 注册)
- 通信协议权威定义(HTTP + Kafka)
- SDK 测试套件:
FakeBatchPlatform+@BatchWorkerTest,租户写 handler 测试用
| 模块 | 端口 | 职责 |
|---|---|---|
batch-common |
— | 公共枚举、DTO、Kafka 消息定义、运行时基础设施 |
batch-test-support |
— | 跨模块 Testcontainers / ArchUnit 测试支撑(仅 test scope) |
batch-trigger |
18081 | Quartz JDBC 集群调度、手动触发、Misfire / readiness defer 处理 |
batch-orchestrator |
18082 | 唯一状态主机,负责 DAG 编排、分片、路由、Outbox |
batch-worker-core |
— | Worker 注册、心跳、执行适配器基座 |
batch-worker-import |
18083 | 导入链路:RECEIVE → PREPROCESS → PARSE → VALIDATE → LOAD → FEEDBACK |
batch-worker-export |
18084 | 导出链路:PREPARE → GENERATE → STORE → REGISTER → COMPLETE |
batch-worker-dispatch |
18085 | 分发链路:PREPARE → DISPATCH → ACK → RETRY/COMPENSATE → COMPLETE |
batch-worker-process |
18086 | 加工链路:READ → TRANSFORM → STAGE → PUBLISH → FEEDBACK(含 WAP 模式 + SQL transform 插件) |
batch-worker-atomic |
18087 | 专用原子任务 worker(ADR-029):shell / sql / stored-proc / http 执行器,不带文件 pipeline;dual-use(RCE 级)能力隔离到最小权限进程 |
batch-console-api |
18080 | 控制台 REST API、审计、AI 辅助 |
sdk/java/core |
— | 租户自托管 Worker SDK(ADR-035 核心)。对外发布 jar,零 Spring 依赖,HTTP+Kafka 协议 + handler 运行时 + 4-state 治理。详见 sdk/java/core/README.md |
sdk/java/spring |
— | SDK 可选 Spring Boot 适配层(Boot 3.x / 4.x);@Component 即自动注册 + SmartLifecycle 接管 start/stop。详见 sdk/java/spring/README.md |
sdk/java/testkit |
— | SDK 测试套件:FakeBatchPlatform in-process 平台 fake + @BatchWorkerTest JUnit 扩展,租户写 handler 测试用。生产不引入。详见 sdk/java/testkit/README.md |
batch-e2e-tests |
— | 端到端集成测试(内嵌 Orchestrator + Worker) |
security-scan |
— | 本地/CI 安全扫描编排工具(独立模块,不进 root reactor) |
sdk/python |
— | Python SDK(ADR-035 跨语言对等实现)。Python 3.12+ async-only,pydantic v2 / httpx / aiokafka。独立工具链(pip),不进 Maven reactor;跨 SDK contract drift 由 Lane P guard。详见 sdk/python/README.md |
sdk/go / sdk/typescript / sdk/rust |
— | 独立工具链的跨语言 SDK(ADR-035 对等实现),与 Java/Python 共享契约 fixture;语言清单、安装与使用见 sdk/README.md |
平台运行时固定 10 个逻辑模块:从
batch-common到batch-console-api(含batch-worker-atomic)。其中batch-worker是聚合(aggregator)模块,下挂 6 个子模块:core/import/export/process/dispatch/atomic(对应上表batch-worker-*)。根 Maven reactor 当前有 10 个 module path:7 个平台 / 测试模块 + 3 个 Java SDK 模块;Go / Python / Rust / TypeScript SDK、load-tests、security-scan是独立工具链或独立 reactor。调整范围参考docs/architecture/project-structure.md。
| 层次 | 选型 |
|---|---|
| 运行时 | JDK 21(LTS), Spring Boot 4.1.1 |
| 消息队列 | Apache Kafka(版本由 Spring Boot BOM 管理) |
| 数据库 | PostgreSQL 17(JSONB、TIMESTAMPTZ) |
| 对象存储 | S3 兼容对象存储(本地默认 MinIO) |
| 调度器 | Quartz Scheduler + JDBC JobStore 集群 |
| 数据迁移 | Flyway |
| ORM | MyBatis(mapper + XML;配置态与运行态同一套) |
- JDK 21(LTS;主工程
maven.compiler.release=21,2026-06 由 25 降到主流 LTS,代码仅用 ≤21 特性)。CI / Docker base image 已统一 temurin 21,本地务必对齐(用 17 等更低版本会编译失败,因平台用了 record pattern / sequenced collection 等 21 特性) - Docker(用于本地基础设施)
- Maven 3.9+
仓库提供统一模板 .env.example。本地首次启动先复制模板:
cp .env.example .env.local不要提交包含真实凭据的环境文件。生产密钥应由密钥管理系统或部署平台注入,不应直接使用模板部署。
docker compose --env-file .env.local -f docker-compose.yml up -d本地服务端口:
| 服务 | 地址 |
|---|---|
| PostgreSQL | localhost:15432(用户 batch_user,密码 batch_pass_123) |
| Valkey(Redis 协议兼容) | localhost:16379 |
| Kafka | localhost:19092 |
| Kafka UI | http://localhost:18090 |
| S3 兼容对象存储 API | http://localhost:19000(本地 MinIO,Bucket: batch-dev) |
| MinIO Console | http://localhost:19001 |
本地 MinIO 对象排查优先用 mc。常用命令见 对象存储后端(S3 协议)配置与多云接入。
./mvnw -ntp -q compile本地轻量门禁:
bash scripts/local/strict-verify.sh根目录 make / make help 只展示本地常用目标,不会自动创建 Python 虚拟环境;完整目标清单见 Makefile。
CI 同步类检查可单独运行:
bash scripts/python.sh scripts/ci/check-config-governance.py
bash scripts/python.sh scripts/ci/check-feature-switch-registry.py
bash scripts/python.sh scripts/ci/check-config-defaults-sync.py
bash scripts/python.sh scripts/ci/check-helm-env-sync.py
bash scripts/ci/check-sql-config-boundaries.sh
helm lint helm/batch-platform# 单元测试
./mvnw -ntp -pl batch-common,batch-orchestrator test -Dgroups=\!e2e
# 集成测试(需要 Docker)
./mvnw -ntp -pl batch-orchestrator -am verify
# 端到端测试
./mvnw -ntp -pl batch-e2e-tests -am verify -Dgroups=e2e默认分支每天北京时间 21:31 检查当天代码/配置变更;有变更时,在临时 GitHub-hosted runner 上依次运行 sim-harness all 和 BE-ACC 严格真实数据验证。仅 Markdown/RST 文档及 LICENSE、NOTICE 变更会跳过。该验证不替代 PR Gate 或合并后的 Full CI;流程和手动触发方式见 CI 体系说明。
./scripts/docker/up-apps.sh停止应用容器栈:
./scripts/docker/down-apps.sh测试环境可切换为:
COMPOSE_ENV_FILE=.env.test ./scripts/docker/up-apps.sh生产环境模板可切换为:
COMPOSE_ENV_FILE=.env.prod ./scripts/docker/up-apps.sh控制面容量压测使用独立的 Trigger benchmark profile,不会污染日常 local 配置:
COMPOSE_BENCHMARK=1 ./scripts/docker/up-apps.sh triggerload-tests/scripts/run-p2-capacity-profile.sh 会校验 profile、入口并发和 Hikari 池预算;未启用该 profile 时直接拒绝执行。
完整环境边界见 环境配置边界。
dry-run 与容量验证建议按“功能基线 → 阶梯容量 → 故障恢复 → 正式任务混压”推进,验收口径见 批量日 dry-run 增强计划、测试文档索引 与 上线就绪检查。
首次启动或代码有变更时,先构建本地应用模块:
bash scripts/local/build-apps.sh再启动本地联调环境:
bash scripts/local/start-all.sh停止本地 Java 进程:
bash scripts/local/stop-all.sh说明:
start-all.sh默认只启动基础依赖和本地 Java 进程,不自动 Maven 打包- 如需“构建 + 启动”,可使用
BUILD=1 bash scripts/local/start-all.sh
- 登录页:
/console-login.html - 默认 seed 账号:
adminauditorconfig-admin
- 登录接口:
POST /api/console/auth/login - 仓库只保存密码哈希,不保存明文密码
- 登录成功后返回 JWT,后续请求使用
Authorization: Bearer <token>
- 配置分类与生效方式见 配置治理:
STATIC、DYNAMIC_DB、SECRET、RESTART_REQUIRED - 全局开关登记源见 feature-switch-registry.yml,人读版见 特性开关
- Helm 部署通过 ConfigMap / Secret checksum 触发需要重启的配置滚动更新
- 动态配置发布需要版本号、旧版本拒绝、发布后确认和多实例一致性指标,不建议给普通属性随意加
@RefreshScope
控制台前端仓库与后端平级,位于 ../batch-console:
- API 客户端(axios 封装、拦截器、SSE)在
../batch-console/src/api - 由本后端 OpenAPI 生成的 TS 类型在
../batch-console/src/types/api.generated.ts,修改/api/console/**接口后需同步重新生成 - 本地运行说明见 batch-console README
./scripts/docker/up-observability.sh停止观测栈:
./scripts/docker/down-observability.sh也可以用更短的入口:
make observability-up
make observability-downscripts/data/load-system-test-data.sh系统测试数据脚本位于 scripts/data/,测试策略详见 docs/testing/README.md。
DB (job_task: READY)
→ Outbox (outbox_event: NEW)
→ Kafka (batch.task.dispatch.{import|export|process|dispatch|atomic})
→ Worker CLAIM (job_task: RUNNING)
→ Worker EXECUTE
→ Worker REPORT (job_task: SUCCESS/FAILED)
→ Orchestrator 汇总 (job_instance 状态推进)
关键约束:
- Orchestrator 是唯一状态主机,Worker 不得直接写入
job_instance/workflow_run/workflow_node_run outbox_event必须与任务状态写入在同一事务- Worker 执行前必须先 CLAIM,不得绕过
- Kafka 仅负责异步驱动,数据库是业务状态事实来源
- MyBatis:配置态、定义态、运行态、实例态、状态推进、复杂查询一律走
*Mapper+resources/mapper/*.xml(见 ADR-001)。 - 行载体命名:落
domain/entity的表行投影统一*Entity后缀(可为 Javarecord或@Dataclass,依模块惯例);禁止为区分技术栈再使用*Record后缀表示「配置态」。 - 禁止
spring-boot-starter-data-jdbc、@EnableJdbcRepositories、CrudRepository及与 MyBatis 同一表 / 同一写路径的双入口(不得 Repository + Mapper 混写)。 JdbcTemplate:仅用于锁表、极薄支撑查询等,不作为默认业务 CRUD 手段。
| 数据库 | Schema | 用途 |
|---|---|---|
batch_platform |
batch, quartz |
平台元数据、运行态、编排态 |
batch_business |
biz |
业务导入/导出目标表 |
测试分三层推进,详见 docs/testing/full-project-test-plan.md:
| 层次 | 框架 | 范围 |
|---|---|---|
| 单元测试 | JUnit 5 + Mockito | 领域逻辑、状态机、路由策略 |
| 集成测试 | Spring Boot Test + Testcontainers | Mapper、Repository、Service 与真实 DB/Kafka |
| 端到端测试 | Awaitility + 内嵌 App | 完整 Kafka 主链(IMPORT/EXPORT/DISPATCH) |
集成测试和端到端测试使用 Testcontainers 自动启动 PostgreSQL 17 和 Apache Kafka,无需预先安装本地服务。
| 文档 | 说明 |
|---|---|
| 文档总入口 | docs/ 目录分层、角色阅读路径、归档与状态规则 |
| 文档治理 | 文档索引、状态、待办、归档和漂移检查规则 |
| 约定与 CI 周期复核 | 前后端规范漂移、守卫漏扫/误拦与人工/AI 复核入口;本轮证据见审计快照 |
| 运维手册总入口 | 部署、容量、灰度、观测、应急和配置治理 SOP |
| 设计文档索引 | 系统设计文档入口,含数据模型、流程、接口与专题设计 |
| 项目结构 | 当前 Maven reactor、平台运行时模块、SDK、文档/脚本目录与运行系统边界 |
| SDK 总入口 | 租户自托管 Worker SDK 使用说明书(选语言 / 安装 / 跑 / 测 / 排障),配套 docs/sdk/README.md 文档索引 |
| 架构文档索引 | 系统流程、模块通信、扩展性评估与 ADR 决策索引(含推荐阅读顺序) |
| AGENTS.md | 工程基线约束,供 AI 辅助开发时参考 |
| LICENSE | Apache-2.0 许可声明 |
| NOTICE | 第三方声明和合规入口 |
| CONTRIBUTING.md | 贡献和提交约定 |
| SECURITY.md | 安全漏洞报告入口 |
| 开源工程治理规范 | 仓库保护、依赖/供应链、安全响应和高风险变更流程 |
| CHANGELOG.md | 版本变更记录 |
| 测试文档索引 | 测试计划、覆盖矩阵、门禁规则和测试报告总入口 |
| API 文档索引 | 控制台接口协议、OpenAPI 和对接说明 |
| 阶段计划索引 | 工程化借鉴、Spring Boot 工程化样板计划与优秀系统能力对照表 |
| 配置治理 | 配置项分类、动态配置版本、发布确认、checksum 滚动重启与一致性指标 |
| 本地开发 | 环境搭建、调试、常见问题 |
| CI 体系 | PR / full-ci / staging 门禁流水线说明 |
| 安全扫描 | 本地漏洞自测组合:secret、依赖、SAST、镜像、ZAP |
| SonarQube 扫描与门禁 | Sonar 本地一键扫描、报告解读与 CI 质量门禁配置 |
| 特性开关 | 跨模块开关登记、配置注入、灰度和回滚 |
| 观测栈 | Prometheus / Loki / Tempo / OTel 部署与排障 |
| 运维演练剧本 | on-call 场景剧本:发现 → 定位 → 恢复 |
| Docker 部署 | 容器化部署指南 |
| 上线就绪检查 | 后端交付上线完整性就绪检查表 |
| 代码量统计 | 统计口径说明与最新快照 |
| 控制台侧边栏菜单树 | 前端 sidebar 分组、页面可见角色与操作权限边界 |
| 观测栈 Docker 环境 | Prometheus / Exporter / OTel Collector / Tempo / Loki / Grafana 的独立启动与管理 |
| 运行时通信 | 模块间消息协议与接口规范 |
| 平台 Worker 续跑位点 | checkpoint 断点续跑的位点语义与运维说明 |
| 历史设计差距审计 | 2026-04-09 时点快照,仅用于历史审计 |
| 默认运行参数 | 调度器、Worker、Outbox 等默认参数说明 |
| Flyway 迁移脚本 | 数据库迁移脚本目录 |
仓库同时包含调度控制面、五类 Worker、数据库迁移、五语言 SDK、部署和运维资产。开始修改前,先按变更类型确认系统边界和需要同步的契约:
| 改动类型 | 主要位置 | 必须同步核对 |
|---|---|---|
| Console API 与管理能力 | batch-console-api、docs/api/ |
OpenAPI、权限、租户隔离、错误码,以及配对前端生成类型和调用方 |
| 调度、状态机与补偿 | batch-trigger、batch-orchestrator |
事务、Outbox、CAS、幂等、重试、业务日和故障恢复 |
| Worker 执行链路 | batch-worker/* |
claim/report、lease、取消、checkpoint、资源隔离与失败恢复 |
| 数据库与持久层 | db/migration、Mapper XML |
只新增 Flyway 迁移;核对锁、约束、RLS、分区、归档和回滚风险 |
| 五语言 SDK | sdk/、共享 fixture |
wire contract、常量、生命周期和 Java/Python/Go/TypeScript/Rust 一致性 |
| 部署与运维 | deploy/、helm/、Compose、scripts/ |
配置事实源、Secret、环境变量、生产 overlay、runbook 和失败退出码 |
| 文档与发布 | README*、docs/、CHANGELOG.md |
更新权威文档、目录索引及用户、部署、契约或安全变更记录 |
推荐流程:
- 从最新
main创建短生命周期的feature/*或fix/*分支,保持一个 PR 只有一个清晰意图。 - 修改前阅读 AGENTS.md、工程基线和受影响模块 README;不要跨模块复制逻辑规避边界。
- 按风险补充单元、集成或端到端验证;多模块 Maven 命令使用
-am,真实服务、sim 和性能验证必须与静态门禁分开说明。 - 提交前运行
bash scripts/local/pre-commit-checks.sh;PR 级检查可运行make ci-pr,更大范围回归运行make ci。 - PR 描述列出行为、契约、权限、租户、数据库、配置、部署和回滚影响,并明确已运行、跳过和未运行的验证。
完整开发、验证和 Pull Request 规则见 CONTRIBUTING.md。安全问题请按 SECURITY.md 私下报告,不要在公开 Issue 或 PR 中披露凭据、真实租户数据或可利用漏洞。