【问题标题】:Spring-batch flow / split after a step一步后的弹簧批处理流/拆分
【发布时间】:2013-11-28 14:51:39
【问题描述】:

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

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

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

以下作业将无法编译。 Spring 给我一个错误:'cannot resolve step2'

<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


    【解决方案1】:

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

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

    <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="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 声明,您必须在编译时设置将执行的并行步骤的确切数量,而拆分的目的是在每个流程中使用不同的步骤多次调用同一个。

    您应该查看有关 Scaling and Parallel processes 的文档,分区步骤似乎很适合您的要求。

    【讨论】:

      【解决方案2】:

      当然,您可以在工作中进行拆分!这是 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>
      

      【讨论】:

        【解决方案3】:

        并行步骤将指示每个子列表的不同步骤,我认为这不是您想要的。
        单个Multi-threaded Step 似乎更合适。
        如文档所述,您首先定义一个 TaskExecutor bean,它将在单独的线程中处理每个 chunk。由于 TaskExecutor 使用起来相当简单,您也可以自己调用 TaskExecutor。在这种情况下,您的步骤可以是多线程的,而无需 Spring Batch 了解。

        【讨论】:

        • 感谢您的回答,但这并不能解决我的问题。每个子列表需要由不同的逻辑处理。 (不同的读取和处理逻辑)我将看看多线程步骤。现在我已经解决了我的问题,只需在基于标志的读取和处理步骤中使用 switch 语句。
        【解决方案4】:

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

        <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" />
        

        【讨论】:

        • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
        • 答案可以改进
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-12-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多