🌟 Spring Batch终极指南:原理、实战与性能优化

单机日处理10亿数据?揭秘企业级批处理架构的核心引擎!


一、Spring Batch 究竟是什么?

Spring batch是用于创建批处理应用程序(执行一系列作业)的开源轻量级平台。

1.1 批处理的定义与挑战

批处理(Batch Processing)
大量数据进行无需人工干预的自动化处理,通常具有以下特征:

  • 大数据量(GB/TB级)
  • 长时间运行(分钟/小时级)
  • 无需用户交互
  • 定时/周期执行

传统批处理痛点

传统方案
缺乏容错机制
无状态管理
数据源

1.2 Spring Batch 核心价值

Spring Batch 是 Spring 生态系统中的批处理框架,提供:

  • 健壮的容错机制(跳过/重试/重启)
  • 事务管理(Chunk级别事务)
  • 元数据跟踪(执行状态持久化)
  • 可扩展架构(并行/分区处理)
  • 丰富的读写器(文件/DB/消息队列)

💡 行业地位:金融领域对账、电信话单处理、电商订单结算等场景事实标准


二、核心架构深度解析

2.1 架构组成图解

1
1..*
Job
+String name
+List<Step> steps
+start(Step)
+next(Step)
+decision(JobExecutionDecider)
Step
+ItemReader reader
+ItemProcessor processor
+ItemWriter writer
+Tasklet tasklet
+ChunkOrientedTasklet
JobRepository
+save(JobExecution)
+getLastJobExecution(String jobName, JobParameters)
JobLauncher
+run(Job, JobParameters)

2.2 关键组件职责

组件职责生命周期
Job批处理作业的顶级容器整个批处理过程
Step作业的独立执行单元Job内部阶段
ItemReader数据读取接口(文件/DB/JMS)每个Chunk开始
ItemProcessor业务处理逻辑读取后,写入前
ItemWriter数据写出接口Chunk结束时
JobRepository存储执行元数据(状态/参数/异常)整个执行过程

三、实战:银行交易对账系统

3.1 场景需求

  • 每日处理100万+交易记录
  • 比对银行系统与内部系统的差异
  • 生成差异报告并告警

3.2 系统架构

Spring Batch
Processor
Reader
Writer
银行交易文件
Spring Batch
内部系统数据库
差异报告
告警系统

3.3 代码实现

步骤1:配置批处理作业
@Configuration
@EnableBatchProcessing
public class ReconciliationJobConfig {@Autowiredprivate JobBuilderFactory jobBuilderFactory;@Autowiredprivate StepBuilderFactory stepBuilderFactory;// 定义Job@Beanpublic Job bankReconciliationJob(Step reconciliationStep) {return jobBuilderFactory.get("bankReconciliationJob").incrementer(new DailyJobIncrementer()) // 每日参数.start(reconciliationStep).listener(new JobCompletionListener()).build();}
}
步骤2:配置Step与读写器
@Bean
public Step reconciliationStep(ItemReader<Transaction> reader,ItemProcessor<Transaction, ReconciliationResult> processor,ItemWriter<ReconciliationResult> writer) {return stepBuilderFactory.get("reconciliationStep").<Transaction, ReconciliationResult>chunk(1000) // 每1000条提交.reader(reader).processor(processor).writer(writer).faultTolerant().skipLimit(100) // 最多跳过100条错误.skip(DataValidationException.class).retryLimit(3).retry(DeadlockLoserDataAccessException.class).build();
}// 文件读取器(CSV格式)
@Bean
@StepScope
public FlatFileItemReader<Transaction> reader(@Value("#{jobParameters['inputFile']}") Resource resource) {return new FlatFileItemReaderBuilder<Transaction>().name("transactionReader").resource(resource).delimited().names("id", "amount", "date", "account").fieldSetMapper(new BeanWrapperFieldSetMapper<Transaction>() {{setTargetType(Transaction.class);}}).build();
}// 数据库比对处理器
@Bean
public ItemProcessor<Transaction, ReconciliationResult> processor(JdbcTemplate jdbcTemplate) {return transaction -> {// 查询内部系统记录String sql = "SELECT amount FROM internal_trans WHERE id = ?";BigDecimal internalAmount = jdbcTemplate.queryForObject(sql, BigDecimal.class, transaction.getId());// 比对金额差异if (internalAmount.compareTo(transaction.getAmount()) != 0) {return new ReconciliationResult(transaction, "AMOUNT_MISMATCH", transaction.getAmount() + " vs " + internalAmount);}return null; // 无差异不写入};
}// 差异报告写入器
@Bean
public JdbcBatchItemWriter<ReconciliationResult> writer(DataSource dataSource) {return new JdbcBatchItemWriterBuilder<ReconciliationResult>().itemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>()).sql("INSERT INTO recon_results (trans_id, error_type, detail) " +"VALUES (:transaction.id, :errorType, :detail)").dataSource(dataSource).build();
}
步骤3:启动作业
// 命令行启动(带日期参数)
@SpringBootApplication
public class BatchApplication implements CommandLineRunner {@Autowiredprivate JobLauncher jobLauncher;@Autowiredprivate Job bankReconciliationJob;public static void main(String[] args) {SpringApplication.run(BatchApplication.class, args);}@Overridepublic void run(String... args) throws Exception {JobParameters params = new JobParametersBuilder().addString("inputFile", "classpath:data/trans-20230520.csv").addDate("runDate", new Date()).toJobParameters();jobLauncher.run(bankReconciliationJob, params);}
}

四、高级特性实战

4.1 并行处理(分区10万+记录)

@Bean
public Step masterStep() {return stepBuilderFactory.get("masterStep").partitioner("slaveStep", columnRangePartitioner()).step(slaveStep()).gridSize(8) // 8个并行线程.taskExecutor(new ThreadPoolTaskExecutor()).build();
}@Bean
public Partitioner columnRangePartitioner() {ColumnRangePartitioner partitioner = new ColumnRangePartitioner();partitioner.setColumn("id");partitioner.setTable("transactions");partitioner.setDataSource(dataSource);return partitioner;
}

4.2 断点续跑(从失败处恢复)

# 重启上次失败的执行
java -jar recon.jar \--job.name=bankReconciliationJob \--run.id=1672531200 \restart=true

4.3 邮件告警监听器

public class AlertListener implements StepExecutionListener {@Overridepublic ExitStatus afterStep(StepExecution stepExecution) {if (stepExecution.getStatus() == BatchStatus.FAILED) {sendAlertEmail("批处理作业失败: " + stepExecution.getFailureExceptions());}return ExitStatus.COMPLETED;}private void sendAlertEmail(String message) {// 实现邮件发送逻辑}
}

五、性能优化黄金法则

5.1 读写性能优化矩阵

优化点效果实现方式
合理设置Chunk Size减少事务提交次数通过压测找到最佳值(通常500-5000)
使用游标读取避免OOMJdbcCursorItemReader
分区处理水平扩展Partitioner接口实现
异步ItemProcessor提升处理速度AsyncItemProcessor包装
批量写入优化减少数据库往返JdbcBatchItemWriter

5.2 内存优化配置

# application.properties
spring.batch.job.enabled=true
spring.batch.initialize-schema=always# 事务优化
spring.transaction.timeout=3600 # 1小时事务超时
spring.datasource.hikari.maximum-pool-size=20# JVM参数(10GB数据场景)
-Xmx4g -XX:+UseG1GC -XX:MaxGCPauseMillis=200

六、常见生产问题解决方案

问题1:作业重复执行

解决方案

// 自定义JobParametersIncrementer
public class DailyJobIncrementer implements JobParametersIncrementer {@Overridepublic JobParameters getNext(JobParameters parameters) {return new JobParametersBuilder(parameters).addLong("run.id", System.currentTimeMillis()).toJobParameters();}
}

问题2:大数据量内存溢出

解决方案

@Bean
public JdbcCursorItemReader<Transaction> reader(DataSource dataSource) {return new JdbcCursorItemReaderBuilder<Transaction>().name("transactionReader").dataSource(dataSource).sql("SELECT * FROM transactions WHERE date = ?").rowMapper(new BeanPropertyRowMapper<>(Transaction.class)).preparedStatementSetter((ps, ctx) -> ps.setDate(1, new java.sql.Date(ctx.getJobParameter("runDate")))).fetchSize(5000) // 优化游标大小.build();
}

问题3:作业监控缺失

解决方案:集成Prometheus监控

@Bean
public MeterRegistryCustomizer<MeterRegistry> metrics() {return registry -> {registry.config().commonTags("application", "batch-service");new BatchMetrics().bindTo(registry);};
}

七、最佳实践总结

  1. 事务边界:Chunk Size = 事务粒度
  2. 幂等设计:Writer需支持重复写入
  3. 资源隔离:每个Job独立数据源
  4. 监控告警:Prometheus + Grafana 看板
  5. 版本控制:Liquibase管理数据库变更
需求分析
设计Job/Step
选择读写器
实现处理逻辑
单元测试
性能压测
部署监控

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/913655.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/913655.shtml
英文地址,请注明出处:http://en.pswp.cn/news/913655.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Part 3 Unity VR眼镜端播放器开发与优化】第四节|高分辨率VR全景视频播放性能优化

文章目录《VR 360全景视频开发》专栏Part 3&#xff5c;Unity VR眼镜端播放器开发与优化第一节&#xff5c;基于Unity的360全景视频播放实现方案第二节&#xff5c;VR眼镜端的开发适配与交互设计第三节&#xff5c;Unity VR手势交互开发与深度优化第四节&#xff5c;高分辨率V…

TCP/IP协议基础

TCPIP协议基础 网络模型 -OSI参考模型 -OSI参考模型各层功能 -TCP/IP网络模型 -TCP/IP协议栈OSI参考模型 – 为了解决网络设备之间的兼容性问题&#xff0c;国际标准化组织ISO于1984年提出了OSI RM&#xff08;开放系统互连参考模型&#xff09;。 OSI参考模型一共有七层&#…

【Nginx】Nginx代理WebSocket

1.websocketWebSocket 是一种网络通信协议&#xff0c;它提供了在单个 TCP 连接上进行全双工&#xff08;双向&#xff09;通信的能力假设需求&#xff1a;把 ws://192.168.0.1:8088/ws-api/websocket/pushData代理到ws://192.168.0.156:8888/websocket/pushData&#xff1b;同…

Spring AI Alibaba Graph使用案例人类反馈

1、Spring AI Alibaba Graph 是社区核心实现之一&#xff0c;也是整个框架在设计理念上区别于 Spring AI 只做底层原子抽象的地方&#xff0c;Spring AI Alibaba 期望帮助开发者更容易的构建智能体应用。基于 Graph 开发者可以构建工作流、多智能体应用。Spring AI Alibaba Gra…

本地部署jenkins持续集成

一、准备环境&#xff08;jdk版本跟Tomcat版本要匹配&#xff09; java jdk 环境(版本是11.0.21) jenkins war包(版本是2.440.3) Tomcat (版本是 9.0.84) 二、安装步骤 1、安装jdk环境 1&#xff09;先安装java环境&#xff0c;安装完成后配置环境变量&#xff0c;参考上…

基于Java+Maven+Testng+Selenium+Log4j+Allure+Jenkins搭建一个WebUI自动化框架(1)搭建框架基本雏形

本次框架使用Maven作为代码构建管理&#xff0c;引用了PO模式&#xff0c;将整体的代码分成了页面层、用例层、业务逻辑层。框架搭建流程&#xff1a;1、在pom.xml中引入依赖&#xff1a;<!-- https://mvnrepository.com/artifact/io.appium/java-client --> <depende…

从零构建MCP服务器:FastMCP实战指南

引言&#xff1a;MCP协议与FastMCP框架 Model Context Protocol&#xff08;MCP&#xff09;是连接AI模型与外部服务的标准化协议&#xff0c;允许LLM&#xff08;如Claude、Gemini&#xff09;调用工具、访问数据。然而&#xff0c;直接实现MCP协议需要处理JSON-RPC、会话管理…

基于FPGA的智能小车设计(包含代码)/ 全栈FPGA智能小车:Verilog实现蓝牙/语音/多传感器融合的移动平台

首先先声明一下&#xff0c;本项目已经历多轮测试&#xff0c;可以放心根据我的设计进行二次开发和直接套用&#xff01;&#xff01;&#xff01; 代码有详细的注释&#xff0c;方便同学进行学习&#xff01;&#xff01; 制作不易&#xff0c;记得三连哦&#xff0c;给我动…

Object.defineProperties 详解

Object.defineProperties 详解 Object.defineProperties 是 JavaScript 中用于在一个对象上定义或修改多个属性的方法。它是 Object.defineProperty 的复数版本&#xff0c;允许你一次性定义多个属性。 基本语法 Object.defineProperties(obj, props)obj&#xff1a;要在其上定…

MyBatis-Plus:深入探索与最佳实践

MyBatis-Plus作为MyBatis的增强版&#xff0c;已经在Java开发中得到了广泛应用。它不仅继承了MyBatis的所有功能&#xff0c;还提供了许多强大的扩展功能&#xff0c;帮助开发者提升开发效率和代码质量。本文将深入探讨MyBatis-Plus的高级特性及其在实际项目中的最佳实践。一、…

劳斯莱斯数字孪生技术:重构航空发动机运维的绿色革命

在航空工业迈向智能化的浪潮中&#xff0c;劳斯莱斯以数字孪生技术为核心&#xff0c;构建了发动机全生命周期管理的创新范式。这项技术不仅重新定义了航空发动机的维护策略&#xff0c;更通过数据驱动的决策体系&#xff0c;实现了运营效率与生态效益的双重突破。本文将从技术…

NPM组件 querypilot 等窃取主机敏感信息

【高危】NPM组件 querypilot 等窃取主机敏感信息 漏洞描述 当用户安装受影响版本的 querypilot 等NPM组件包时会窃取用户的主机名、用户名、工作目录、IP地址等信息并发送到攻击者可控的服务器地址。 MPS编号MPS-2kgq-v17b处置建议强烈建议修复发现时间2025-07-05投毒仓库np…

创业商业融资计划书PPT模版

创业商业融资计划书PPT模版&#xff1a;https://pan.quark.cn/s/25a043e4339e

解决GitHub仓库推送子文件夹后打不开的问题

从你描述的情况来看&#xff0c;IELTS_AI_Assessment 很可能被识别为了 Git 子模块&#xff08;submodule&#xff09;&#xff0c;而不是普通文件夹&#xff0c;这会导致在 GitHub 上无法直接打开查看内容。以下是具体原因和解决办法&#xff1a;为什么文件夹无法打开&#xf…

Web后端开发-请求响应

文章目录概述请求Postman简单参数原始方式SpringBootRequestParam注解小结实体参数数组集合参数日期参数Json参数路径参数总结响应响应-案例概述 请求 Postman 简单参数 原始方式 // 1. 简单参数 // 原始方式RequestMapping("/simpleParam")public String …

Javascript基础内容回顾—变量提升、事件循环和闭包等内容

以下是前端面试中 JavaScript 基础易错问题的详解&#xff0c;结合常见考点和易混淆概念进行解析&#xff1a; ⚠️ 一、变量作用域与提升 var vs let/const ◦ 变量提升&#xff1a;var 声明的变量会提升到作用域顶部&#xff08;值为 undefined&#xff09;&#xff0c;而 …

UNIX程序设计基本概念和术语

unix体系结构从严格意义上说&#xff0c;可将操作系统定义为一种软件&#xff0c;它控制计算机硬件资源&#xff0c;提供程序运行环境。我们通常将这种软件称为内核&#xff08;kernel&#xff09;&#xff0c;因为它相对较小&#xff0c;而且位于环境的核心。内核的接口被称为…

【WEB】Polar靶场 16-20题 详细笔记

目录 十六.签到题 十七.签到 十八.session文件包含 PHP 伪协议&#xff08;PHP Stream Wrappers&#xff09; base64加解密获取源代码 Session文件包含 namenameShell 是什么&#xff1f; 十九.Dont touch me 二十.robots robots.txt 十六.签到题 把didino改成didiy…

数据结构*搜索树

什么是搜索树 搜索树是一种树形数据结构&#xff0c;用于高效地存储和检索数据。其核心特点是每个节点包含一个键&#xff08;Key&#xff09;&#xff0c;并遵循特定的排序规则。常见的搜索树有二叉搜索树、自平衡二叉树、多叉搜索树等。AVL树、红黑树、Splay树都属于自平衡二…