Spring Batch 如何健壮可重启可追溯 SKIP/RETRY/RESTART策略的应用

前提:你已经有了一定的Spring基础

你已经可以跑动一个简单的Spring batch 的实例


参考:http://www.cnblogs.com/gulvzhe/archive/2011/10/25/2224249.html

http://www.cnblogs.com/cdutedu/p/3789396.html

先盗几个图




JobLauncher 指定一个 JobRepository

JobRepository包含了一些传入JOB的参数,主要有六个表去存储


每个JOB可以对应多个Step


		 ...<batch:step id="aStep" next="bStep">
			<batch:tasklet>
				<batch:chunk reader="aReader" writer="aWriter" processor="aProcessor" commit-interval="1000" />
			</batch:tasklet>
		</batch:step>...

tesklet里面的工作块为chunk,每个chunk执行完commit-interval,即提交一次,可以同时开多个chunk


每个STEP 这样执行


(以下一段摘抄)

从DB或是文件中取出数据的时候,read()操作每次只读取一条记录,之后将读取的这条数据传递给processor(item)处理,框架将重复做这两步操作,直到读取记录的件数达到batch配置信息中”commin-interval”设定值的时候,就会调用一次write操作。然后再重复上图的处理,直到处理完所有的数据。当这个Step的工作完成以后,或是跳到其他Step,或是结束处理。


那么问题来了?读取数据到处理的时候发生了异常如何处理?会不会导致整个批处理中断呢?

有异常没有捕获,到最上层也没有的话整个进程会挂掉,导致整个批处理中断。


显然,为了不影响后面的处理,要么捕获异常,打出日志,跳过。要么,重试(在IO超时或者表锁定的情况下是很有效的-瞬态情况)。

即使有中断,我们也需要重启JOB


以上几种正好对应Spring-Batch中的 SKIP\RETYR\RESTART

一、SKIP

<job id="importProductsJob">
<step id="importProductsStep">
<tasklet>
<chunk reader="reader" writer="writer" commit-interval="100"
skip-limit="10">
<skippable-exception-classes>
<include class="org.springframework.batch
➥ .item.file.FlatFileParseException" />
</skippable-exception-classes>
</chunk>
</tasklet>
</step>
</job>

skippable-exception-classes 里面配需要SKIP的异常类型

skip-limit 最多可以容错次数,超过这个数,该STEP中断





也可以添加listener去打日志

<bean id="skipListener" class="com.manning
➥ .sbia.ch08.skip.DatabaseSkipListener">
<constructor-arg ref="dataSource" />
</bean>
<job id="importProductsJob"
xmlns="http://www.springframework.org/schema/batch">
<step id="importProductsStep">
<tasklet>
<chunk reader="reader" writer="writer"
commit-interval="100" skip-limit="10">
<skippable-exception-classes>
<include class="org.springframework.batch.item.file
➥ .FlatFileParseException" />
</skippable-exception-classes>
</chunk>
<listeners>
<listener ref="skipListener" />
</listeners>
</tasklet>
</step>
</job>

二、Retrying on error

主要针对于IO操作的、并发等,瞬态的错误

类似于SKIP的配置

<job id="importProducsJob">
<step id="importProductsStep">
<tasklet>
<chunk reader="reader" writer="writer" commit-interval="100"
retry-limit="3">
<retryable-exception-classes>
<include class="org.springframework.dao
➥.OptimisticLockingFailureException" />
</retryable-exception-classes>
</chunk>
</tasklet>
</step>
</job>

如果你不想重试次数达到后,由于这些错误导致STEP的中断退出,可以混合RETRY和SKIP两者。

<job id="job">
<step id="step">
<tasklet>
<chunk reader="reader" writer="writer" commit-interval="100"
retry-limit="3" skip-limit="10">
<retryable-exception-classes>
<include class="org.springframework.dao
➥ .DeadlockLoserDataAccessException" />
</retryable-exception-classes>
<skippable-exception-classes>
<include class="org.springframework.dao
➥ .DeadlockLoserDataAccessException" />
</skippable-exception-classes>
</chunk>
</tasklet>
</step>
</job>


你也可以通过自定义的策略来控制重试

<job id="retryPolicyJob"
xmlns="http://www.springframework.org/schema/batch">
<step id="retryPolicyStep">
<tasklet>
<chunk reader="reader" writer="writer" commit-interval="100"
retry-policy="retryPolicy" />
</tasklet>
</step>
</job>
<bean id="retryPolicy" class="org.springframework
➥.batch.retry.policy.ExceptionClassifierRetryPolicy">
<property name="policyMap">
<map>
<entry key="org.springframework.dao.ConcurrencyFailureException">
<bean class="org.springframework.batch.retry
➥.policy.SimpleRetryPolicy">
<property name="maxAttempts" value="3" />
</bean>
</entry>
<entry key="org.springframework.dao
➥ .DeadlockLoserDataAccessException">
<bean class="org.springframework.batch.retry
➥ .policy.SimpleRetryPolicy">
<property name="maxAttempts" value="5" />
</bean>
</entry>
</map>
</property>
</bean>

你也可以添加Listener

配置方法类似同SKIP,继承RetryListenerSupport,配置在retry-listeners


你还可以通过RetryTemplate来重试。RetryTemplate配置属性retryPolicy


三、重启

重启的重点是能够保存之前的job repository,自带的reader,都可以,自己写的Reader需要继承接口

Spring batch 默认是会重启的

allow-start-if-complete配置在tasklet上,决定了tasklet会不会在JOB重试的时候,重试该STEP(可能是下个STEP发生了异常)。

start-limit用来控制STEP级别的重试次数,重试次数结束后,JOB中断退出。




处理在STEP中的状态,已经处理了很多ITEM,失败了?
middle of a chunk-oriented step,item级别的重启。首先是reader的重启。
如果你需要你自己写的ITEM的reader,也可以实现重启的话,需要实现ItemStram的接口,将对于item 计数的值,保存到executionContext,重启的时候去读取。





  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Batch中,可以使用Spring Retry框架来实现在数据库连接失败时进行重试。具体步骤如下: 1. 在pom.xml文件中添加Spring Retry的依赖: ``` <dependency> <groupId>org.springframework.retry</groupId> <artifactId>spring-retry</artifactId> <version>1.3.1</version> </dependency> ``` 2. 创建一个RetryTemplate对象,设置重试策略(例如,设置最大重试次数、重试的异常类型等): ``` @Bean public RetryTemplate retryTemplate() { RetryTemplate retryTemplate = new RetryTemplate(); SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy(); retryPolicy.setMaxAttempts(3); Map<Class<? extends Throwable>, Boolean> exceptionsMap = new HashMap<>(); exceptionsMap.put(SQLException.class, true); ExceptionClassifierRetryPolicy exceptionClassifierRetryPolicy = new ExceptionClassifierRetryPolicy(); exceptionClassifierRetryPolicy.setPolicyMap(exceptionsMap); retryTemplate.setRetryPolicy(exceptionClassifierRetryPolicy); return retryTemplate; } ``` 3. 在Step中使用RetryTemplate执行任务(例如,执行查询语句): ``` @Bean public Step step1() { return stepBuilderFactory.get("step1") .<Person, Person>chunk(10) .reader(itemReader()) .processor(itemProcessor()) .writer(itemWriter()) .faultTolerant() .retryTemplate(retryTemplate()) .retryLimit(3) .build(); } ``` 在上面的代码中,我们通过调用faultTolerant()方法来启用重试机制,并设置了RetryTemplate和最大重试次数。当查询语句执行失败时,Spring Batch会自动使用RetryTemplate进行重试,直到达到最大重试次数或任务成功执行为止。 注意:为了确保数据库连接失败时可以进行重试,需要在数据库连接URL中添加retry参数,例如: ``` jdbc:mysql://localhost/mydb?autoReconnect=true&useSSL=false&retry=true ``` 这样,当数据库连接失败时,驱动程序会自动尝试重新连接数据库,并通过Spring Retry进行重试。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值