默认情况下,Spring批处理作业因执行期间引发的任何错误而失败。但是,有时,我们可能需要提高应用程序的弹性来处理间歇性故障。在本快速教程中,我们将探索如何在Spring Batch框架中配置重试逻辑。
假设我们有一个批处理作业,它读取输入的CSV文件:
username, userid, transaction_date, transaction_amount sammy, 1234, 31/10/2015, 10000 john, 9999, 3/12/2015, 12321
然后,它通过点击REST端点以获取用户的age和postCode属性来处理每条记录:
<b>public</b> <b>class</b> RetryItemProcessor implements ItemProcessor<Transaction, Transaction> {
@Override
<b>public</b> Transaction process(Transaction transaction) throws IOException {
log.info(<font>"RetryItemProcessor, attempting to process: {}"</font><font>, transaction);
HttpResponse response = fetchMoreUserDetails(transaction.getUserId());
</font><font><i>//parse user's age and postCode from response and update transaction</i></font><font>
...
<b>return</b> transaction;
}
...
}
</font>
最后,它生成一个合并的输出XML:
<transactionRecord>
<transactionRecord>
<amount>10000.0</amount>
<transactionDate>2015-10-31T00:00:00+05:30</transactionDate>
<userId>1234</userId>
<username>sammy</username>
<age>10</age>
<postCode>430222</postCode>
</transactionRecord>
...
</transactionRecord>
现在,如果由于某些网络缓慢而导致与REST端点的连接超时怎么办?如果是这样,我们的批处理作业将失败。
在这种情况下,我们希望重试失败的项目两次。因此,让我们将批处理作业配置为在失败的情况下最多执行三个重试:
@Bean
<b>public</b> Step retryStep(
ItemProcessor<Transaction, Transaction> processor,
ItemWriter<Transaction> writer) throws ParseException {
<b>return</b> stepBuilderFactory
.get(<font>"retryStep"</font><font>)
.<Transaction, Transaction>chunk(10)
.reader(itemReader(inputCsv))
.processor(processor)
.writer(writer)
.faultTolerant()
.retryLimit(3)
.retry(ConnectTimeoutException.<b>class</b>)
.retry(DeadlockLoserDataAccessException.<b>class</b>)
.build();
}
</font>
在这里,我们调用faultTolerant() 以启用重试功能。此外,我们使用retry和retryLimit分别定义了符合重试条件的异常和项的最大重试计数。
看一下上述配置的XML等效配置:
<batch:job id=<font>"retryBatchJob"</font><font>>
<batch:step id=</font><font>"retryStep"</font><font>>
<batch:tasklet>
<batch:chunk reader=</font><font>"itemReader"</font><font> writer=</font><font>"itemWriter"</font><font>
processor=</font><font>"retryItemProcessor"</font><font> commit-interval=</font><font>"10"</font><font>
retry-limit=</font><font>"3"</font><font>>
<batch:retryable-exception-classes>
<batch:include <b>class</b>=</font><font>"org.apache.http.conn.ConnectTimeoutException"</font><font>/>
<batch:include <b>class</b>=</font><font>"org.springframework.dao.DeadlockLoserDataAccessException"</font><font>/>
</batch:retryable-exception-classes>
</batch:chunk>
</batch:tasklet>
</batch:step>
</batch:job>
</font>