【问题标题】:Retry not working with Spring Batch with Java Config重试不使用带有 Java Config 的 Spring Batch
【发布时间】:2019-10-03 19:52:01
【问题描述】:

我有以下配置的 Spring 批处理作业:

@Bean
public Job myJob(Step step1, Step step2, Step step3) {
    return jobs.get("myJob").start(step1).next(step2).next(step3).build();
}

@Bean
public Step step1(ItemReader<String> myReader,
                ItemProcessor<String, String> myProcessor,
                ItemWriter<String> myWriter) {
    return steps.get("step1").<String, String>chunk(1)
            .reader(myReader)
            .faultTolerant().retryLimit(3).retry(MyException.class)
            .processor(myProcessor)
            .writer(myWriter)
            .build();
}

@Bean
@StepScope
public MyReader myReader() {
    return new MyReader();
}
@Bean
public MyProcessor myProcessor() {
    return new MyProcessor();
}
@Bean
public MyWriter myWriter() {
    return new MyWriter();
}

当 MyReader 类抛出 MyException 时,它将停止作业的执行,而不使用以下堆栈跟踪重试:

2019-05-16 14:45:09.460 ERROR 22485 --- [           main] o.s.batch.core.step.AbstractStep         : Encountered an error executing step step1 in job myJob

org.springframework.batch.core.step.skip.NonSkippableReadException: Non-skippable exception during read
    at org.springframework.batch.core.step.item.FaultTolerantChunkProvider.read(FaultTolerantChunkProvider.java:105) ~[spring-batch-core-4.0.1.RELEASE.jar:4.0.1.RELEASE]
    at org.springframework.batch.core.step.item.SimpleChunkProvider$1.doInIteration(SimpleChunkProvider.java:116) ~[spring-batch-core-4.0.1.RELEASE.jar:4.0.1.RELEASE]

【问题讨论】:

    标签: java spring-boot spring-batch spring-retry


    【解决方案1】:

    似乎从 2.2.0 开始,重试功能已从 Spring Batch 中撤出。它现在是新库 Spring Retry 的一部分。 https://docs-stage.spring.io/spring-batch/docs/current/reference/html/retry.html#retry

    通过声明式重试处理此问题的步骤:

    第 1 步: 在应用程序中包含@EnableRetry

    Spet 2: 添加基于https://github.com/spring-projects/spring-retry#additional-dependencies的aop starter

    分级 runtime('org.springframework.boot:spring-boot-starter-aop')

    Maven

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-aop</artifactId>
        <scope>runtime</scope>
    </dependency>
    

    Spet 3: 在MyReader 中包含@Retryable

    @Override
    @Retryable(include = { MyException.class }, maxAttempts = 5)
    public String read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {
    

    示例代码签入github:https://github.com/atulkulkarni18/spring-batch-reader-retry

    示例输出:

    MyReader : 0
    MyProcessor : 0
    MyWriter : [0]
    MyReader : 1
    MyProcessor : 1
    MyWriter : [1]
    MyReader : 2
    MyProcessor : 2
    MyWriter : [2]
    MyReader : 3
    ****
    MyReader : 3
    ****
    MyReader : 3
    ****
    MyReader : 3
    MyProcessor : 3
    MyWriter : [3]
    MyReader : 4
    MyProcessor : 4
    MyWriter : [4]
    MyReader : 5
    

    【讨论】:

    • @Mahmoud Ben Hassine 我已经签入了 github 中的代码。如果我遗漏了什么,你能告诉我吗?似乎重试正在阅读器中工作。
    • @adesai 有帮助吗?
    • 我想使用 faultTolerant 进行重试,因为它提供了整个步骤的重试。 Mahmoud Ben Hassine 关于重试不使用项目阅读器是正确的。
    • 但是@Retryable 正在使用项目阅读器(基于控制台输出),不是吗?
    【解决方案2】:

    当 MyReader 类抛出 MyException 时,它会停止作业的执行而不重试

    重试策略不适用于项目阅读器。因此,即使您将异常声明为可重试并且读取器抛出该异常,重试策略也不会被调用。

    重试策略仅适用于处理器和写入器。

    【讨论】:

    • 您能看看:github.com/atulkulkarni18/spring-batch-reader-retry 吗?似乎重试甚至对读者也有效。
    • @Mahmoud Ben Hassine - 感谢您的回答,但您知道为什么该政策不适用于项目阅读器吗?这没有多大意义!
    • @Atul K 在您分享的链接中,重试功能是在阅读器本身使用 spring-retry 实现的。这与您在应用于ChunkProcessor 的容错步骤中指定的重试策略不同,后者不调用读取器。
    • @adesai 这样做的原因是因为item reader的合约是“forward only”,在重试的情况下没有办法(在当前界面)回到之前的位置.
    • 在高层次上,面向块的步骤调用两个组件:ChunkProvider(通过调用项目读取器提供块)和ChunkProcessor(通过调用处理器 + 写入器处理块)。当您在容错步骤中指定重试策略时,将使用重试策略配置FaultTolerantChunkProcessor(对于块提供程序而言并非如此)。因此,重试策略适用于处理器和写入器,但不适用于读取器。
    猜你喜欢
    • 2017-07-28
    • 2016-09-23
    • 2015-12-10
    • 1970-01-01
    • 2021-08-27
    • 1970-01-01
    • 1970-01-01
    • 2015-12-08
    相关资源
    最近更新 更多