Spring Batch核心模型与快速上手详解

Spring Batch核心模型与快速上手详解

定位: Batch 第 01 篇,讲透批处理定位、Job/Step/Chunk 核心模型、Reader-Processor-Writer 与执行元数据体系

适用版本:Spring Batch 5.x(Spring Boot 3.x)


目录


一、批处理定位

1.1 典型场景

场景 例子
数据导入/导出 对账文件导入、报表导出
批量加工 夜间结算、积分计算、数据迁移
定期同步 与外部系统的数据交换

1.2 与在线处理的差异

维度 在线(请求) 批处理
触发 用户请求 定时/手动/事件
数据量 单条/少量 大批量(万~亿级)
目标 低延迟 高吞吐
失败处理 即时报错 记录位置、可重跑
时效 实时 离线/窗口期

批处理的核心诉求:大批量、可重跑、可监控、失败可恢复------Spring Batch 就是围绕这些构建的框架。


二、核心模型

2.1 三层结构

复制代码
Job(一次批处理任务)
 └── Step(处理阶段)
      └── Chunk(读-处理-写的批量单元)
概念 职责
Job 批处理的完整定义:由若干 Step 组成,带参数
JobInstance Job + 参数的一次逻辑运行
JobExecution JobInstance 的一次物理执行(重跑产生新 execution)
Step 独立的处理阶段,有自己的状态
StepExecution Step 的一次执行记录

Job/参数/执行的区分是理解重跑与监控的基础:同一 Job 不同参数是不同实例;同一实例失败重跑是新的 execution。

2.2 两种 Step

类型 用途
Tasklet Step 执行单个任务(清理文件、准备环境),非面向数据
Chunk-oriented Step 面向数据的分块处理(主流),Reader-Processor-Writer

2.3 Chunk 的语义

复制代码
每次读取 chunkSize 条 → 逐条 Processor → 整块 Writer 写出并提交
   → 提交点:一个 Chunk 一个事务

提交点(commit interval)= chunkSize:每处理完一个 Chunk 提交一次。意义:

  • 失败只影响当前 Chunk(之前的已提交);
  • 内存占用可控(一次只持有一个 Chunk);
  • 重跑从上次失败的 Chunk 附近继续。

三、Reader-Processor-Writer

3.1 三件套职责

组件 接口 行为
ItemReader read() 逐条读取,返回 null 表示读完
ItemProcessor process(item) 逐条转换/校验/过滤;返回 null 表示丢弃该条
ItemWriter write(Chunk) 接收整块数据批量写出

3.2 常见实现

复制代码
Reader:FlatFileItemReader(文件)、JdbcCursorItemReader / JdbcPagingItemReader(库)、
        KafkaItemReader、自定义
Writer:JdbcBatchItemWriter(批量 SQL)、FlatFileItemWriter、
        RepositoryItemWriter、自定义

3.3 代码示例(骨架)

java 复制代码
@Bean
Step importStep(JobRepository repo, PlatformTransactionManager tm) {
    return new StepBuilder("import", repo)
        .<Input, Entity>chunk(500, tm)          // chunkSize = 500
        .reader(reader())                        // 读
        .processor(processor())                  // 处理(可选)
        .writer(writer())                        // 写
        .build();
}

@Bean
Job importJob(JobRepository repo, Step importStep) {
    return new JobBuilder("importJob", repo)
        .start(importStep)
        .build();
}

四、执行元数据与仓库

4.1 三个核心组件

组件 职责
JobRepository 持久化 Job/Step 执行状态(开始/结束时间、状态、提交数、读写计数)
JobLauncher 启动 Job(传入参数)
JobExplorer 只读查询执行历史(监控/审计/判断是否可重跑)

4.2 元数据表

Spring Batch 需要一组元数据表(BATCH_JOB_INSTANCE、BATCH_JOB_EXECUTION、BATCH_STEP_EXECUTION 等)存执行状态:

复制代码
作用:
  ① 记录每次执行的状态与进度 → 支撑重启
  ② 防止同一 JobInstance 并发重复执行
  ③ 提供监控与审计数据

Boot 下引入依赖后自动建表(生产建议显式管理表结构)。元数据库可与业务库分离。

4.3 状态机

复制代码
Job/Step 状态:
   STARTING → STARTED → COMPLETED / FAILED / STOPPED
失败后可重启(从失败处继续,见第 02 篇)

五、快速上手

5.1 Boot 最小配置

复制代码
依赖:spring-boot-starter-batch
数据源:元数据表所在库(默认自动建表)
配置:
   spring.batch.jdbc.initialize-schema=always   # 开发用;生产手动建表
   spring.batch.job.enabled=false                # 关闭启动自动跑(按需触发)

5.2 触发方式

复制代码
启动时自动执行(Boot 默认,可关)
定时调度(@Scheduled / 调度平台触发)
手动/接口触发(JobLauncher.run(job, params))

5.3 参数与幂等

复制代码
JobParameters 区分运行(如 date=2026-08-26)
同参数重复启动:默认拒绝(已完成的实例)→ 需加时间戳参数或用识别参数

六、总结

  1. 定位:大批量、离线、可重跑的加工框架;吞吐优先,与在线处理互补。
  2. 核心模型:Job(任务)→ Step(阶段,Tasklet/Chunk)→ Chunk(提交单元);JobInstance 与 JobExecution 区分逻辑运行与物理执行。
  3. 三件套:Reader 逐条读、Processor 逐条处理(可丢弃)、Writer 按块写;提交点 = chunkSize。
  4. 元数据:JobRepository 持久化状态支撑重启与防重;JobLauncher 启动、JobExplorer 查询;依赖一组元数据表。
  5. 上手:Boot starter + 数据源;触发方式多样;用参数区分运行,注意重复启动行为。

七、常见高频面试题

1. Spring Batch 的核心概念有哪些?

要点:三层模型。Job 是一次批处理任务的定义,由多个 Step 组成;Step 是独立处理阶段,分 Tasklet(单任务)与 Chunk 面向数据两种;Chunk 是"读-处理-写"的批量单元与事务提交点。执行概念:JobInstance(Job + 参数的逻辑运行)、JobExecution(一次物理执行,重跑产生新 execution)、StepExecution。配套组件:JobRepository(状态持久化)、JobLauncher(启动)、JobExplorer(查询)。

2. chunk size(提交间隔)是什么?怎么定?

要点:chunkSize 决定一次读取-处理-写入的批量大小,也是事务提交点------每处理完一个 Chunk 提交一次。影响:太小则提交频繁、吞吐低;太大则内存占用高、失败回滚代价大、重启粒度粗。设定依据:单条处理成本、批量写入效率(如批量 SQL 的最佳批大小)、内存限制、可接受的失败回滚范围。常见从几百起,压测调优。它本质是"吞吐与失败代价"的平衡。

3. ItemProcessor 返回 null 会怎样?和抛异常有什么区别?

要点:返回 null 表示过滤掉该条------数据被跳过不写出,批处理继续,这是"校验不通过则丢弃"的正常手段(如脏数据)。抛异常则不同------异常触发错误处理(重试/跳过策略,未配置则 Step 失败)。区分:业务上"这条不要了"用 null;"这条处理失败要按错误策略处理"抛异常。配合 skip 策略,抛异常也可配置为跳过并记录。

4. Spring Batch 如何记录和管理任务执行状态?

要点:通过 JobRepository 把执行元数据持久化到一组元数据表:BATCH_JOB_INSTANCE(逻辑实例)、BATCH_JOB_EXECUTION(每次执行的状态、开始/结束时间、退出码)、BATCH_STEP_EXECUTION(每步的读写计数、提交数、状态)。作用:① 支撑重启------从失败位置继续;② 防止同一实例并发重复执行;③ 监控审计------JobExplorer 查询。所以 Spring Batch 需要一个数据源存元数据,可与业务库分离。

5. JobInstance、JobExecution、JobParameters 的关系?

要点:Job 是任务定义;JobParameters 标识一次运行的输入(如日期);Job = Job + 参数 确定一个 JobInstance(逻辑运行);每次实际执行产生一个 JobExecution。例如同一天对账参数相同 → 同一 JobInstance;第一次跑失败、重跑一次 → 两个 JobExecution 属于同一 JobInstance。重启机制依赖此模型:失败的 execution 可重启,已完成的 instance 默认拒绝重复运行。

6. Reader/Writer 有哪些常用实现?游标读和分页读的区别?

要点:常用:读------FlatFileItemReader(文件)、JdbcCursorItemReader(游标)、JdbcPagingItemReader(分页)、KafkaItemReader;写------JdbcBatchItemWriter(批量 SQL)、FlatFileItemWriter、RepositoryItemWriter。游标读:数据库游标流式读取,内存占用低,但要求连接在读取期间保持打开(事务/连接生命周期要注意);分页读:按页查询(LIMIT/OFFSET 或 keyset),无长游标问题,适合数据在读取中可能变化的场景,但深分页有性能问题(用 keyset)。选择按数据量与一致性需求。

7. Spring Batch 和用 @Scheduled 写个循环处理有什么区别?

要点:@Scheduled + 循环是手工批处理:要自己实现进度记录、失败重跑、提交控制、并发防护、监控,规模一大问题全暴露。Spring Batch 提供框架级能力:提交点控制(chunk)、状态持久化(可重启续跑)、跳过/重试策略、并行处理、执行元数据监控、防重复执行。适用:数据量大、要求可靠可重跑、需要审计监控的批处理用框架;小数据量简单任务用定时循环即可。按复杂度选工具。

8. 同一个 Job 如何避免被重复执行?

要点:机制:Spring Batch 用 JobParameters 确定 JobInstance;对已完成的 JobInstance,再次用相同参数启动默认抛 JobInstanceAlreadyCompleteException 拒绝。实践:① 用业务参数(日期)标识运行,同一天不会跑两次;② 需要重跑时用新参数(如加时间戳或重跑标记);③ 并发防护靠元数据表的实例唯一性。理解参数语义是控制"防重与重跑"的关键。

9. 元数据表应该放在哪?和业务库一起吗?

要点:可以分离。元数据表存框架执行状态,与业务数据无关;放在独立库的好处:批处理元数据操作不影响业务库、权限与备份策略独立、多个批处理应用可共享。也可同库(简单场景)。注意:① 生产显式管理表结构(不依赖自动建表);② 元数据库故障会导致任务无法启动/记录,也需保障可用;③ 历史数据要定期清理(元数据会增长)。

10. 如何触发一个 Batch Job?

要点:方式:① 应用启动自动执行(Boot 默认,生产常关闭);② 定时调度------@Scheduled 或外部调度平台(推荐生产用调度平台,有失败告警/依赖编排);③ 手动/接口触发------注入 JobLauncher 调 run(job, params),适合补数/重跑;④ 事件触发(消息到达)。生产实践:调度平台定时 + 支持手动重跑;触发时传入正确参数区分运行;监控执行状态与时长。

相关推荐
缓慢更新1 小时前
AI 辅助生成单测:从接口定义到用例的流水线
java·服务器·前端·网络·数据库·人工智能
LMT流氓兔3 小时前
第五单元——第十六课:给书店助手加上网页界面
java·开发语言·jvm·人工智能·oracle·langchain·1024程序员节
wangbing11254 小时前
平台介绍-modbus设备调试
java
开开心心就好4 小时前
音频降噪剪辑工具,音量裁剪一键处理
运维·服务器·前端·spring·ocr·音视频·1024程序员节
西索斯coding5 小时前
gpt-image-2.5-sunburst 和 gemini-3.1-flash-image 差多少?60 组项目素材的成功成本评测框架
java·linux·gpt·ai
wuminyu5 小时前
Java字节码学习总结:字节码如何加载、解析和执行
java·linux·c语言·jvm·c++
Flynn Liang5 小时前
大模型怎么自己调函数?Spring AI 2.0 Tool Calling 自动循环原理 + 完整时序图
java·人工智能·spring·agent·函数调用·springai·toolcalling
乌暮6 小时前
请求进门先安检:Spring 拦截器与统一功能实战指南
java·开发语言·后端·学习·spring
学长毕设7 小时前
基于SpringBoot的烘焙商品商品系统-附源码
java·spring boot·后端