如何使用Spring批处理正确地聚合和拆分作业

时间:2017-04-06 07:32:23

标签: spring spring-batch

我需要实现一个批处理作业,它分割XML,处理部件并在之后聚合它们。聚合需要进一步处理。

帐户部件的处理非常昂贵。在下图中,处理部分对一个人的每个帐户采取行动(一个人的帐户数量因btw而异)。

structure of the XML

示例输入文件:

<?xml version="1.0" encoding="UTF-8"?>
<Persons>
    <Person>
        <Name>Max Mustermann</Name>
        <Accounts>
            <Account>maxmustermann</Account>
            <Account>esel</Account>
            <Account>affe</Account>
        </Accounts>
    </Person>
    <Person>
        <Name>Petra Pux</Name>
        <Accounts>
            <Account>petty</Account>
            <Account>petra</Account>
        </Accounts>
    </Person>
        <Person>
        <Name>Einsiedler Bob</Name>
        <Accounts>
            <Account>bob</Account>
        </Accounts>
    </Person>
</Persons>

对于每个人的每个帐户,请执行以下操作: 调用REST服务,例如

GET / account / {person} / {account} / logins

结果为包含聚合的logins-xml:

的每个Person调用一个rest服务

POST / analysis / logins / {person}

<Person>
    <Name>Max Mustermann</Name>
    <Accounts>
        <Account>
            <LoginCount>22</LoginCount>
            <Name>maxmustermann</Name>
        </Account>
        <Account>
            <LoginCount>42</LoginCount>
            <Name>esel</Name>
        </Account>
        <Account>
            <LoginCount>13</LoginCount>
            <Name>affe</Name>
        </Account>
    </Accounts>
</Person>

我对API没有任何影响,所以我需要更新人员包。

我如何实现并行化,从而构建我的弹簧批量应用程序?

我找到了一些起点,但没有一个真的令人满意。

我是否应该在一个步骤中处理帐户数据,返回属于每个帐户的项目并在下一步中为每个项目进行轮询并汇总这些项目或者我应该在帐户步骤中实施并行化并聚合在这一步中,引入下一步进一步处理?

第一种方法的问题:我应该如何知道所有项目已经到达以开始聚合?

第二种方法的问题(或者更确切地说是问题):手动实现并行化(例如Java Futures)而不是将其留给Spring批处理是否常见?

什么是 Spring Batch 方式?

谢谢,托马斯

1 个答案:

答案 0 :(得分:1)

你没有在你的问题中解释很多事情 - 你的出发点以及那些不满意的原因?

此外,您应该已经显示了一个示例输入和输出xml。你的最后一段是非常神秘的阅读&amp;明白了,请写得更好。

话虽如此,我想从Java的角度来看,您输入的类型为List<Person>,其中Person就像 -

public class Person{ private List<Account> accounts; .... .... }

我仍然不知道你想要的输出,也不确定你的意思是什么?

请解释这些要点,我会修改我的答案。

据我了解聚合要求,Spring批处理已经在中写入,因此在没有任何显式聚合的情况下应该已经处理了部分。

如果我已正确理解您的输入结构和处理需要,您应该使用Spring Batch PartitioningList<Person>(从XML读取记录)进行分区,或者直接对XML进行分区({3}} {3}})或者您可以将XML划分为多个较小的xml,并可以使用Using split command and SystemCommandTasklet

没有必要一次性启动所有分区步骤,因为您可以使用concurrencyLimit TaskExecutor并行启动一小组分区步骤。

可以通过多个线程写入单个文件或通过多个线程等写入多个文件来制定各种策略。

标准Spring Batch方式将是y个并行线程中的两个读取x个人(即每个线程x个人),并行处理每个人,然后以块的形式写入单个目标或多个目标。

除以N - 分区中的总人数,在ItemProcessor中为每个人调用REST服务,并在处理器中准备目标Person对象。所需的输出人数将作为chunk-size设置发送给作者。在步骤ItemReader中标记从属步骤组件ItemProcessorItemWriter@StepScope,并且每个从属步骤将在其自己的线程中运行。

希望它有所帮助,让我知道您面临的具体挑战。