Spring-batch 流程/一步后拆分

问题描述 投票:0回答:4

我正在构建一个 spring-batch 解决方案,其中包含以下过程:

第1步:将一个列表拆分为多个列表 步骤2:处理每个子列表 第 3 步:合并子列表

生成的子列表可以并行处理,并且根据 spring-batch 文档,这是支持的。遗憾的是,我只能找到以并行步骤开始的 spring-batch 示例作业,而不是按顺序开始的示例。

以下作业将无法编译。 Spring 给我一个错误:“无法解析第 2 步”

<batch:job id="webServiceJob2">
    <batch:step id="step1" next="step2"></batch:step>
    <batch:split id="step2" next="step3"></batch:split>
    <batch:step id="step3"></batch:step>
</batch:job>

那么,如何将作业配置为首先运行单个步骤,然后并行运行多个步骤,然后运行最后一个步骤?

java spring concurrency spring-batch
4个回答
5
投票

我偶然发现了这个问题,询问 split 是如何工作的,也许这个答案来得有点晚(一年),但我开始了......

“拆分”的问题本身并不是一个步骤,但您是按原样命名(和引用)它的:

<batch:job id="webServiceJob2">
    <batch:step id="step1" next="step2"></batch:step>
    <batch:split id="step2" next="step3"></batch:split> <!-- This is not a step -->
    <batch:step id="step3"></batch:step>
</batch:job>

正确的语法是:

<batch:job id="webServiceJob2">
    <batch:step id="step1" next="split_step2"></batch:step>
    <batch:split id="split_step2" next="step3">
        <flow> 
             <step id="step2_A_1" ... next="step2_A_2"/>
             <step id="step2_A_2" ... />
        </flow>
        <flow> 
             <step id="step2_B_1" ... />
        </flow>
    </batch:split>
    <batch:step id="step3"></batch:step>
</batch:job>

但这不是您想要实现的目标,因为通过

split
声明,您必须在编译时设置将执行的并行步骤的确切数量,而 split 的目的是在每个流程中使用不同的步骤,而不是调用多个步骤多次相同。

您应该检查有关缩放和并行进程的文档,分区步骤似乎很适合您的要求。


1
投票

当然,你可以在工作中途分裂!这是 Spring Batch In Action (2012) 中的示例。

<batch:job id="importProductsJob">
  <batch:step id="decompress" next="readWrite">
    <batch:tasklet ref="decompressTasklet"/>
  </batch:step>
  <batch:split id="readWrite" next="moveProcessedFiles">
    <batch:flow>
      <batch:step id="readWriteBookProduct"/>
    </batch:flow>
    <batch:flow>
      <batch:step id="readWriteMobileProduct"/>
    </batch:flow>
  </batch:split>
  <batch:step id="moveProcessedFiles">
    <batch:tasklet ref="moveProcessedFilesTasklet" />
  </batch:step>
</batch:job>

0
投票

并行步骤将指示每个子列表的不同步骤,我认为这不是您想要的。
单个多线程步骤似乎更合适。
如文档所述,您首先定义一个

TaskExecutor
bean,它将在单独的线程中处理每个 chunk。由于 TaskExecutor 使用起来相当简单,您也可以自己调用 TaskExecutor。在这种情况下,您的步骤可以是多线程的,而 Spring Batch 不需要了解它。


0
投票

执行以下操作希望对您有所帮助:

<job id="job">
    <step id="step_0" next="split_1">
        <tasklet ref="taskletStep_4"/>
    </step>
    <split id="split_1" next="step_5" task-executor="taskExecutor"> 
        <flow>
            <step id="step_1" next="step_2">
                <tasklet ref="taskletStep_1"/>
            </step>
            <step id="step_2" next="step_3">
                <tasklet ref="taskletStep_2"/>
            </step>
            <step id="step_3">
                <tasklet ref="taskletStep_3"/>
            </step>
        </flow>
        <flow>
            <step id="step_4">
                <tasklet ref="taskletStep_4"/>
            </step>
        </flow>
    </split>
    <step id="step_5">
        <tasklet ref="taskletStep_5"/>
    </step>
</job>

<beans:bean id="taskletStep_1" class="com.test.batch.parallelstep.step.SimpleStep1" />
<beans:bean id="taskletStep_2" class="com.test.batch.parallelstep.step.SimpleStep2" />
<beans:bean id="taskletStep_3" class="com.test.batch.parallelstep.step.SimpleStep3" />
<beans:bean id="taskletStep_4" class="com.test.batch.parallelstep.step.SimpleStep4" />
<beans:bean id="taskletStep_5" class="com.test.batch.parallelstep.step.SimpleStep5" />

<beans:bean id="taskExecutor" class="org.springframework.core.task.SimpleAsyncTaskExecutor" />
© www.soinside.com 2019 - 2024. All rights reserved.