我正在使用Spring Batch同时运行多个作业。
我配置了taskExecutor corePoolSize=40
,
从分割的平面文件中读取作业并写入数据库。
问题是如果拆分文件超过corePoolSize
(例如,g文件数> = 40),那么同时运行的其他作业就会卡住,因为一个分区步骤正在使用整个taskExecutor。
我正在使用MultiResourcePartitioner
和FlatFileItemReader
。
要解决此问题,我尝试将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。
我该如何解决这种情况?