如何通过可重启性实现容错的Spring批处理作业。我有一个包含 8个Milion 记录的表,然后使用 JdbcPagingItemReader 阅读器配置了一个作业以获取记录,并使用 AmqpItemWriter 将记录排队到 rabbitMQ 。 Challange是当我突然停止工作然后重新启动时,出现异常。预期的行为:
以下是配置:
@Bean
public JdbcPagingItemReader<NotificationRequest> notificationRequestJdbcPagingItemReader() {
JdbcPagingItemReader<NotificationRequest> reader = new JdbcPagingItemReader<>();
reader.setDataSource(this.dataSource);
reader.setFetchSize(1000);
reader.setRowMapper(new SmsSQLRowMapper());
PostgresPagingQueryProvider queryProvider = new PostgresPagingQueryProvider();
queryProvider.setSelectClause("subscriber_fk, event_time, record_flag, batch_date, message_type, cents_loanable, request_id, reason_code");
queryProvider.setFromClause("from tbl_sms_tracker_new");
Map<String, Order> sortKeys = new HashMap<>(1);
sortKeys.put("request_id", Order.ASCENDING);
queryProvider.setSortKeys(sortKeys);
reader.setQueryProvider(queryProvider);
return reader;
}
@Bean
public ItemWriter<NotificationRequest> notificationRequestAmqpItemWriter() {
AmqpTemplate aTemplate = (AmqpTemplate) applicationContext.getBean("amqpTemplate");
AmqpItemWriter<NotificationRequest> itemWriter = new AmqpItemWriter<>(aTemplate);
return itemWriter;
}
@Bean
public Step step1() {
return stepBuilderFactory.get("notificationStep1")
.<NotificationRequest, NotificationRequest>chunk(1000)
.reader(notificationRequestJdbcPagingItemReader())
.writer(notificationRequestAmqpItemWriter())
.faultTolerant()
.build();
}
@Bean
public Job job() {
return jobBuilderFactory.get("notificationJob")
.start(step1())
.build();
}
答案 0 :(得分:0)
预期行为:
- 成功重启工作
如果您突然停止工作(kill -9
),则JobRepository
无法知道您当前的工作状态,因为以前没有人告诉过您。您的工作可能不是,但仍处于STARTED
状态(已被杀死)。这就是为什么在尝试重新启动终止的作业时会遇到异常的原因。您必须手动告诉作业存储库,您知道执行失败或应被视为中止。此处的更多详细信息:https://docs.spring.io/spring-batch/4.0.x/reference/html/job.html#aborting-a-job
- 从作业停止的ID开始读取表格
突然停止作业时,当前执行上下文未正确保存到作业存储库中。在这种情况下,当您重新启动作业时,项目读取器将从最后一个“保存点”(即最后一个成功持久保存的执行上下文)中读取数据。但是,如果您优雅地停止工作,您提到的预期行为将得到兑现。