Spring Batch Partition Step排气所有taskExecutor

时间:2017-03-29 02:45:30

标签: java spring multithreading spring-batch

我正在使用Spring Batch同时运行多个作业。

我配置了taskExecutor corePoolSize=40, 从分割的平面文件中读取作业并写入数据库。

问题是如果拆分文件超过corePoolSize(例如,g文件数> = 40),那么同时运行的其他作业就会卡住,因为一个分区步骤正在使用整个taskExecutor。

我正在使用MultiResourcePartitionerFlatFileItemReader

要解决此问题,我尝试将MultiResourcePartitioner扩展为使用如下所示的网格大小,并使用MultiResourceItemReader进行存档。

// if file count is 8 and gridsize is 2 then  
partition-0 : [file0, ..., file3]
partition-1 : [file4, ..., file7]

,代码如下

@Override
protected Map<String, ExecutionContext> createPartitionMap(String serviceCode, String targetPath, int gridSize) {

    Map<String, ExecutionContext> partitionMap = new HashMap<>(gridSize);

    File inputFile = new File(targetPath);
    Collection<File> files;
    if (inputFile.isDirectory()) {
        files = FileUtils.listFiles(new File(targetPath), null, true);
    } else {
        files = new ArrayList<>();
        files.add(inputFile);
    }

    int fileCount = files.size();
    int fileIndex = 0;

    for (File file : files) {

        int mapIndex = fileIndex % gridSize;
        String partitionKey = String.format("partition-%d", mapIndex);

        ExecutionContext context;
        if (partitionMap.containsKey(partitionKey)) {
            context = partitionMap.get(partitionKey);
        } else {
            context = new ExecutionContext();
            partitionMap.put(partitionKey, context);
        }

        List<Resource> resources;
        if (context.containsKey(BatchJobConfig.PARAM_FILE_RESOURCE)) {
            resources = (List<Resource>) context.get(BatchJobConfig.PARAM_FILE_RESOURCE);
        } else {
            resources = new ArrayList<>();
        }

        resources.add(new FileSystemResource(file.getPath()));
        context.put(BatchJobConfig.PARAM_FILE_RESOURCE, resources);

        fileIndex++;
    }

    logger.info(partitionMap.toString());

    return partitionMap;
}

但它不起作用,因为在多线程上使用MultiResourceItemReader似乎不是线程安全的。

所以我希望每个步骤(或作业)都限制使用池计数或以不同方式为每个作业分配taskExecutor。

我该如何解决这种情况?

0 个答案:

没有答案