Spring批处理分区无休止地执行1步(很多次 - 循环)

时间:2015-12-11 03:11:11

标签: multithreading spring spring-batch

我有一个包含大量xml文件的文件夹。我想配置分区以创建许多分区,每个分区将处理可配置数量的文件。分区工作罚款(我检查调试模式并返回正确的执行上下文)。但问题是,尽管分区器创建了多个执行上下文,但步骤仍在执行多次。在这个例子中,我只有3个xml文件。每个分区将处理2个文件。 我将整个项目上传到github:https://github.com/tungtran89/spring-batch-partition

请给我建议,谢谢!

这是分区程序

public class FilePartitioner implements Partitioner {

private String xmlFolderLocation;
private int filePerThread;

@Override
public Map<String, ExecutionContext> partition(int gridSize) {
    Assert.hasLength(xmlFolderLocation);
    Map<String, ExecutionContext> executionContexts = new HashMap<String, ExecutionContext>();
    File xmlDir = new File(xmlFolderLocation);
    if (xmlDir.isDirectory()) {
        File[] files = xmlDir.listFiles();
        int fileCount = 0;
        int totalFileCount = 0;
        int partitionCount = 0;
        Map<String, String> chunk = new HashMap<String, String>();
        for (File file: files) {
            if (file.isFile()) {
                if (fileCount < filePerThread && totalFileCount < files.length) {
                    totalFileCount++;
                    chunk.put(file.getName(), file.getAbsolutePath());
                    fileCount = chunk.size();
                }
                if (fileCount == filePerThread || totalFileCount == files.length) {
                    // load enough file to this partition.
                    // create a new partition by creating new ExecutionContext and new chunk
                    partitionCount++;
                    ExecutionContext stepExecutionContext = new ExecutionContext();
                    stepExecutionContext.put("chunk", chunk);
                    chunk = new HashMap<String, String>();
                    executionContexts.put(String.valueOf("partition" + partitionCount), stepExecutionContext);
                    fileCount = 0;
                }
            }
        }
    }
    return executionContexts;
}

}

弹簧配置文件

 <bean id="filePartitioner" class="com.tung.FilePartitioner" scope="step">
    <property name="xmlFolderLocation" value="target\test-classes\data\XML_FILES"/>
    <property name="filePerThread" value="2"/>
</bean>

<bean id="xmlLoadReader" scope="step" class="com.tung.XMLPrintingLoadReader">
    <property name="chunk" value="#{stepExecutionContext['chunk']}"/>
</bean>
<bean id="xmlProcessor" scope="step" class="com.tung.XMLPrintingFileProcessor"/>
<bean id="xmlWriter" scope="step" class="com.tung.XMLPrintingWriter"/>

<bean id="xmlLoadTaskExecutor"
      class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
    <property name="corePoolSize" value="5" />
    <property name="maxPoolSize" value="5" />
</bean>

<batch:step id="slaveStep">
    <batch:tasklet transaction-manager="transactionManager">
        <batch:chunk reader="xmlLoadReader" processor="xmlProcessor" writer="xmlWriter" commit-interval="5"/>
    </batch:tasklet>
</batch:step>

<batch:job id="xmlLoader">
    <batch:step id="master">
        <batch:partition step="slaveStep" partitioner="filePartitioner">
            <batch:handler grid-size="2" task-executor="xmlLoadTaskExecutor"/>
        </batch:partition>
    </batch:step>
</batch:job>

读者

public class XMLPrintingLoadReader implements ItemReader<List<File>> {

private static Logger logger = LoggerFactory.getLogger(XMLPrintingLoadReader.class);
private static int instanceCount = 0;
private int readMethodInvocationCount = 0;
private final int instanceId = instanceCount;

private Map<String, String> chunk;

public XMLPrintingLoadReader() {
    instanceCount++;
}

@Override
public List<File> read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {
    synchronized (this) {
        readMethodInvocationCount++;
    }
    logger.info("Thread " + Thread.currentThread().getName() + " is invoking method read() " +
            "of com.tung.XMLPrintingLoadReader[" + instanceId + "] " + readMethodInvocationCount + " times.");
    List<File> fileList = new ArrayList<File>();
    for (Map.Entry<String, String> entry : chunk.entrySet()) {
        File file = new File(entry.getValue());
        fileList.add(file);
    }
    return fileList;
}

public Map<String, String> getChunk() {
    return chunk;
}

public void setChunk(Map<String, String> chunk) {
    this.chunk = chunk;
}

}

日志文件:

INFO  XMLPrintingLoadReader:37 - Thread xmlLoadTaskExecutor-1 is invoking method read() of com.tung.XMLPrintingLoadReader[0] 1 times.
INFO  XMLPrintingLoadReader:37 - Thread xmlLoadTaskExecutor-2 is invoking method read() of com.tung.XMLPrintingLoadReader[1] 1 times.
INFO  XMLPrintingLoadReader:37 - Thread xmlLoadTaskExecutor-2 is invoking method read() of com.tung.XMLPrintingLoadReader[1] 2 times.
INFO  XMLPrintingLoadReader:37 - Thread xmlLoadTaskExecutor-1 is invoking method read() of com.tung.XMLPrintingLoadReader[0] 2 times.
INFO  XMLPrintingLoadReader:37 - Thread xmlLoadTaskExecutor-2 is invoking method read() of com.tung.XMLPrintingLoadReader[1] 3 times.
INFO  XMLPrintingLoadReader:37 - Thread xmlLoadTaskExecutor-1 is invoking method read() of com.tung.XMLPrintingLoadReader[0] 3 times.
INFO  XMLPrintingLoadReader:37 - Thread xmlLoadTaskExecutor-2 is invoking method read() of com.tung.XMLPrintingLoadReader[1] 4 times.
INFO  XMLPrintingLoadReader:37 - Thread xmlLoadTaskExecutor-1 is invoking method read() of com.tung.XMLPrintingLoadReader[0] 4 times.
INFO  XMLPrintingLoadReader:37 - Thread xmlLoadTaskExecutor-2 is invoking method read() of com.tung.XMLPrintingLoadReader[1] 5 times.
INFO  XMLPrintingLoadReader:37 - Thread xmlLoadTaskExecutor-1 is invoking method read() of com.tung.XMLPrintingLoadReader[0] 5 times
INFO  XMLPrintingLoadReader:37 - Thread xmlLoadTaskExecutor-1 is invoking method read() of com.tung.XMLPrintingLoadReader[0] 6 times.
INFO  XMLPrintingLoadReader:37 - Thread xmlLoadTaskExecutor-2 is invoking method read() of com.tung.XMLPrintingLoadReader[1] 6 times.
INFO  XMLPrintingLoadReader:37 - Thread xmlLoadTaskExecutor-1 is invoking method read() of com.tung.XMLPrintingLoadReader[0] 7 times.
INFO  XMLPrintingLoadReader:37 - Thread xmlLoadTaskExecutor-2 is invoking method read() of com.tung.XMLPrintingLoadReader[1] 7 times.
INFO  XMLPrintingLoadReader:37 - Thread xmlLoadTaskExecutor-1 is invoking method read() of com.tung.XMLPrintingLoadReader[0] 8 times.
INFO  XMLPrintingLoadReader:37 - Thread xmlLoadTaskExecutor-2 is invoking method read() of com.tung.XMLPrintingLoadReader[1] 8 times.

0 个答案:

没有答案