Spring批处理:容错

时间:2017-05-30 06:39:12

标签: spring spring-batch fault-tolerance

我有以下步骤:

    return stepBuilderFactory.get("billStep")
            .allowStartIfComplete(true)
            .chunk(20000)
            .reader(billReader)
            .processor(billProcessor)
            .faultTolerant()
            .skipLimit(Integer.MAX_VALUE)
            .skip(BillSkipException.class)
            .listener(billReaderListener)
            .listener(billSkipListener)
            .writer(billRepoItemWriter)
            .build();

我的理解是否正确,容错意味着当billProcessor中抛出异常时,它将在跳过侦听器中处理,然后下一行/项将在billProcessor中处理?

我在添加调试日志时注意到 - 当处理器中抛出异常时,项目/行被“重新处理”。 (可能是因为faultTolerant配置。 但是,如果我正在处理200万条记录,并且其中300,000条记录被跳过 - 或者抛出跳过异常 - 如果其中一些记录被“重新处理”,那么这不是性能问题。

最大的问题是 - 跳过下一行/项目。它们根本没有在处理器中处理。

如果我删除了faultTolerant和SkipListener - 并直接将跳过的记录保存在数据库中(skiplistener正在做什么) - 它正在运行,但这个解决方案是否正确?

2 个答案:

答案 0 :(得分:0)

没有工作是完美的!发生错误。您可能会收到错误的数据。您可能会忘记在最坏的情况下导致NullPointerException的空检查。今天,我们将如何使用Spring Batch处理错误。在许多情况下,处理过程中遇到的异常不应导致步骤失败,而应跳过。

春季批量跳过技术 使用跳过技术,您可以指定某些异常类型和最多可跳过的项目数,并且只要抛出其中一种可跳过的异常,批处理作业就不会失败,而是会跳过该项目并继续进行下一个。仅当达到跳过项目的最大数量时,批处理作业才会失败。例如,当从您的输入读取记录时发生错误时,Spring Batch提供了在抛出指定的Exception时跳过记录的功能。本节将研究如何使用此技术基于特定的异常跳过记录。选择何时跳过记录涉及两个部分。

1。例外 在什么条件下跳过记录,特别是您将忽略哪些异常。在读取过程中发生任何错误时,Spring Batch都会引发异常。为了确定要跳过的内容,您需要确定要跳过的异常。

2。跳过的记录 在考虑执行步骤失败之前,您将允许跳过多少输入记录。如果您从一百万条记录中跳过一两个记录,那不算什么;但是,从一百万中跳出一百万可能是错误的。确定阈值是您的责任。

整个处理过程发生在每个单独的项目级别,而不是块级别。因此,无论何时我们每当春季批处理都无法一次处理一件物品时。它尝试重新处理/挖掘单个项目,以确定要跳过的确切项目。这很好,因为对于批处理作业,我们期望某些延迟,因为它们通常会处理计划的大数据作业。

答案 1 :(得分:0)

我在添加调试日志时注意到-项目/行是 当处理器中引发异常时,将“重新处理”。 (大概 由于FaultTolerant配置。但是,如果我正在处理2 百万条记录,其中300,000条被跳过-或抛出跳过 例外-如果其中一些是性能不是问题吗 “重新处理”)

我发生了同样的问题,并使用processorNonTransactional方法进行了修复。

    @Bean
    public Step myStep() {
        return stepBuilderFactory.get("myStep")
                .<MyObject, MyObject>chunk(1000)
                .reader(myItemReader())
                .processor(myItemProcessor())
                .writer(jdbcBatchItemWriter())
                .faultTolerant()
                .processorNonTransactional()
                .skip(MyException.class)
                .skipLimit(200)
                .build();
    }