spring batch 相关总结

spring batch 是什么

Spring Batch 作为 Spring 的子项目,是一款基于 Spring 的企业批处理框架。通过它可以构建出健壮的企业批处理应用。Spring Batch 不仅提供了统一的读写接口、丰富的任务处理方式、灵活的事务管理及并发处理,同时还支持日志、监控、任务重启与跳过等特性,大大简化了批处理应用开发,将开发人员从复杂的任务配置管理过程中解放出来,使他们可以更多地去关注核心的业务处理过程。

什么时候使用 spring batch

当需要做大批量的数据处理时,例如:

  • 无需用户交互即可最有效地处理大量信息的自动化,复杂处理。 这些操作通常包括基于时间的事件(例如月末计算,通知或通信)。
  • 在非常大的数据集中重复处理复杂业务规则的定期应用(例如,保险利益确定或费率调整)。
  • 集成从内部和外部系统接收的信息,这些信息通常需要以事务方式格式化,验证和处理到记录系统中。 批处理用于每天为企业处理数十亿的交易。

spring batch 结构

  • 首先,Spring Batch运行的基本单位是一个Job,一个Job就做一件批处理的事情。
  • 一个Job包含很多Step,step就是每个job要执行的单个步骤。
  • Step里面,会有Tasklet,Tasklet是一个任务单元,它是属于可以重复利用的东西。
  • 然后是Chunk,chunk就是数据块,你需要定义多大的数据量是一个chunk。
  • Chunk里面就是不断循环的一个流程,读数据,处理数据,然后写数据。Spring Batch会不断的循环这个流程,直到批处理数据完成。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

Chunk
Spring batch在配置Step时采用的是基于Chunk的机制,即每次读取一条数据,再处理一条数据,累积到一定数量后再一次性交给writer进行写入操作。这样可以最大化的优化写入效率,整个事务也是基于Chunk来进行。
比如我们定义chunk size是50,那就意味着,spring batch处理了50条数据后,再统一向数据库写入。
chunk前面需要定义数据输入类型和输出类型,如果不定义这个类型,会报错。

.<Message, Message>chunk(CHUNK_SIZE)

Reader
Reader顾名思义就是从数据源读取数据。
Spring Batch给我们提供了很多好用实用的reader,基本能满足我们所有需求。比如FlatFileItemReader,JdbcCursorItemReader,JpaPagingItemReader等。也可以自己实现Reader。

Processor
需要定义输入和输出的类型,把输入I通过某些逻辑处理之后,返回输出O。

public interface ItemProcessor<I, O> {
    O process(I item) throws Exception;
}

Writer
Writer顾名思义就是把数据写入到目标数据源里面。
Spring Batch同样给我们提供很多好用实用的writer。比如JpaItemWriter,FlatFileItemWriter,HibernateItemWriter,JdbcBatchItemWriter等。同样也可以自定义。

Listener
Spring Batch同样实现了非常完善全面的listener,listener很好理解,就是用来监听每个步骤的结果。比如可以有监听step的,有监听job的,有监听reader的,有监听writer的。

Skip
Spring Batch提供了skip的机制,也就是说,如果出错了,可以跳过。如果你不设置skip,那么一条数据出错了,整个job都会挂掉。
设置skip的时候一定要设置什么Exception才需要跳过,并且跳过多少条数据。如果失败的数据超过你设置的skip limit,那么job就会失败。
你可以分别给reader和writer等设置skip机制。

writer(testWriter).faultTolerant().skip(Exception.class).skipLimit(SKIP_LIMIT)

Retry
这个和Skip是一样的原理,就是失败之后可以重试,你同样需要设置重试的次数。
同样可以分别给reader,writer等设置retry机制。
如果同时设置了retry和skip,会先重试所有次数,然后再开始skip。比如retry是10次,skip是20,会先重试10次之后,再开始算第一次skip。

搭建 spring batch 代码

pom引用

<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-batch</artifactId>
 </dependency>

配置类

@Configuration
@EnableAutoConfiguration
@EnableBatchProcessing(modular = true)
public class SpringBatchConfiguration {
    @Bean
    public ApplicationContextFactory testJobContext() {
        return new GenericApplicationContextFactory(TestJobConfiguration.class);
    }
}

@EnableBatchProcessing是打开Batch。如果要实现多Job的情况,需要把EnableBatchProcessing注解的modular设置为true,让每个Job使用自己的ApplicationConext。

TestDataBean 数据类

@Entity
@Table(name = "testDataBean ")
public class TestDataBean {

    @Column(name = "id", nullable = false)
    private Integer Id;
    。。。
}

TestJobConfiguration

public class TestJobConfiguration {

	// 注入job工厂
	@Autowired
	private JobBuilderFactory jobBuilderFactory;

	// 注入step工厂
	@Autowired
	private StepBuilderFactory stepBuilderFactory;

	//  得到job bean
	@Bean
	public Job testJob(@Qualifier("TestStep") Step testStep) {
    		return jobBuilderFactory.get("testJob")
            		 .start(testStep)
           		 .build();
	}

	// 得到job中的step的bean
	@Bean
	public Step testStep(@Qualifier("testReader") FlatFileItemReader<TestDataBean> testReader,
                                 @Qualifier("testWriter") JpaItemWriter<TestDataBean> testWriter,
                                 @Qualifier("errorWriter") Writer errorWriter) {
   	return stepBuilderFactory.get("testStep")
            .<TestDataBean , TestDataBean>chunk(CHUNK_SIZE)
            .reader(testReader)
            .listener(new TestReadListener(errorWriter))
            .processor(testProcessor)
            .writer(testWriter)
            .listener(new TestWriteListener())
            .build();
	}

	// readerBean 读取数据
	@Bean
	public FlatFileItemReader<TestDataBean> testReader() {
    		FlatFileItemReader<TestDataBean> reader = new FlatFileItemReader<>();
    		reader.setResource(new FileSystemResource(new File(TEST_FILE)));
    		return reader;
	}

	// processorBean 处理数据
	@Bean
 	public PersonItemProcessor processor() {
 		return new PersonItemProcessor();
  	}

        // writerBean 写入数据
	@Bean
	public JpaItemWriter<TestDataBean> testWriter() {
   		 JpaItemWriter<TestDataBean> writer = new JpaItemWriter<>();
   		 return writer;
	}
}

运行Job

首先我们通过运行起来的Spring application得到jobRegistry,然后通过job的名字找到对应的job。
接着,我们就可以用jobLauncher去运行这个job了,运行的时候会传一些参数,可以解决重复执行同一个job的问题。

	JobRegistry jobRegistry = context.getBean(JobRegistry.class);
        Job job = jobRegistry.getJob(jobName);
        JobLauncher jobLauncher = context.getBean(JobLauncher.class);
        JobExecution jobExecution = jobLauncher.run(job, createJobParams());

Spring Batch数据表

batch_job_instance:这张表能看到每次运行的job名字。
batch_job_execution:这张表能看到每次运行job的开始时间,结束时间,状态,以及失败后的错误消息是什么。
batch_step_execution:这张表你能看到更多关于step的详细信息。比如step的开始时间,结束时间,提交次数,读写次数,状态,以及失败后的错误信息等。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值