Spring Boot集成Spring Batch处理海量离线批处理任务,核心是通过Job+Step+Chunk架构实现可控执行与稳定保障,结合事务控制、重启机制、分页读取、批量写入及并行扩展等手段提升吞吐与可靠性。

Spring Boot 集成 Spring Batch 处理海量离线批处理任务,核心在于合理拆分、可控执行和稳定保障。它不是简单“跑个循环”,而是靠框架内置的事务粒度控制、重启机制、失败跳过与重试能力,把高风险的大批量操作变成可追踪、可恢复、可监控的标准化流程。
明确作业结构:Job + Step + Chunk 是基本骨架
一个批处理任务必须由 Job(作业)统领,Job 包含一个或多个 Step(步骤),每个 Step 以 Chunk(块)为单位处理数据。Chunk 大小直接影响内存占用和事务边界——比如设为 1000,就表示每读取、处理、写入 1000 条记录才提交一次事务。
- Job 是顶层容器,负责整体生命周期管理(启动、停止、重启)
- Step 封装具体逻辑,必须包含 ItemReader(读)、ItemProcessor(转)、ItemWriter(写)三件套
- ChunkSize 不是越大越好:太大易 OOM 或单次失败回滚代价高;太小则事务开销大、吞吐下降。建议从 100~1000 开始压测调优
适配海量场景的关键配置
面对百万级甚至千万级数据,光靠默认配置容易卡死或失败。需针对性调整:
- 数据库元数据表初始化:Spring Batch 默认建 6 张表(如 BATCH_JOB_INSTANCE),务必用真实数据库(MySQL/PostgreSQL),避免 H2 内存库在重启后丢失作业状态
- Step 级事务隔离:在 @Bean 注解的 Step 构建中显式指定事务传播行为,例如 .transactionManager(transactionManager) 并确保其支持长事务
- Reader 分页/游标优化:数据库读取不用一次性 loadAll,优先用 JdbcPagingItemReader(基于 LIMIT/OFFSET)或 JdbcCursorItemReader(基于 JDBC 游标),后者更适合超大数据集且内存友好
- Writer 批量插入:JpaItemWriter 性能差,改用 JdbcBatchItemWriter,并开启 rewriteBatchedStatements=true(MySQL)或 useServerPrepStmts=false(PostgreSQL)提升批量写入效率
让任务真正“离线可控”的实操要点
离线 ≠ 放任不管。要实现无人值守、失败可查、进度可见:
立即学习“Java免费学习笔记(深入)”;
- 启用
@EnableBatchProcessing后,Spring Boot 自动装配 JobLauncher、JobRepository 等基础组件,但需在 application.yml 中配置 job.restartable=true 允许失败后按参数重启 - 通过 JobParameters 传入业务标识(如 date=20260728、source=csv_v2),既支持多实例并行,也便于日志归因和结果追溯
- 加 JobExecutionListener 和 StepExecutionListener,记录开始时间、处理条数、异常堆栈,写入自定义日志表或发送告警
- 禁用自动启动:在 application.yml 中设 spring.batch.job.enabled=false,防止应用启动时误触发;改由 API 接口或定时任务(如 @Scheduled)显式调用 JobLauncher.run()
应对真实海量数据的进阶手段
当单机处理瓶颈明显时,不一定要换技术栈,先用 Spring Batch 原生能力横向扩展:
- 多线程 Step:用 TaskExecutor 配置线程池,在 Step 构建时调用 .taskExecutor(taskExecutor()),适用于 Reader/Writer 无状态、Processor 轻量的场景
- 并行 Flow:将一个大 Job 拆成多个独立 Step,用 FlowBuilder 组合成并行分支(如同时处理用户表和订单表),共用同一个 JobRepository 协调状态
- 远程分区(Remote Partitioning):Master Step 负责切分数据范围(如 id % 10 = 0~9),Worker 节点拉取子任务执行,适合跨机器水平扩容
- 慎用跳过(Skip)和重试(Retry):它们解决的是偶发异常,不是性能问题。高频跳过说明数据质量或逻辑有隐患,应前置清洗而非依赖框架兜底


















