我有一个ItemStreamReader
(extends AbstractItemCountingItemStreamItemReader
),读者本身很快,但以下处理需要相当长的时间。
从业务角度来看,我可以根据需要并行处理任意数量的项目。
当我的ItemStreamReader
正在阅读带有JsonParser的大型JSON文件时,它最终会成为状态。因此,仅向TaskExecutor
添加Step
不起作用,并抛出解析异常以及弹出批处理的以下日志输出:
16:51:41.023 [main] WARN o.s.b.c.s.b.FaultTolerantStepBuilder - Asynchronous TaskExecutor detected with ItemStream reader. This is probably an error, and may lead to incorrect restart data being stored.
16:52:29.790 [jobLauncherTaskExecutor-1] WARN o.s.b.core.step.item.ChunkMonitor - No ItemReader set (must be concurrent step), so ignoring offset data.
16:52:31.908 [feed-import-1] WARN o.s.b.core.step.item.ChunkMonitor - ItemStream was opened in a different thread. Restart data could be compromised.
如何执行我的Step中的处理以由多个线程并行执行?
答案 0 :(得分:2)
Spring Batch提供了许多并行处理的方法。在您的情况下,由于处理似乎是瓶颈,我建议您考虑两个选项:
<强> AsyncItemProcessor / AsyncItemWriter 强>
AsyncItemProcessor
和AsyncItemWriter
协同工作以并行处理块中的项目。您可以将它们视为一种fork / join概念。正常情况下,单个线程读取块中的项目。 AsyncItemProcessor
包装你的普通ItemProcessor
并在另一个线程上执行该逻辑,返回Future
而不是实际项。然后AsyncItemWriter
等待Future
在写入之前返回已处理的项目。这些类可在Spring Batch Integration模块中找到。您可以在此处的文档中详细了解它们:http://docs.spring.io/spring-batch/trunk/reference/html/springBatchIntegration.html#asynchronous-processors
远程分块
AsyncItemProcessor
/ AsyncItemWriter
范例在单个JVM中运行良好,但如果需要进一步扩展处理,可能需要查看远程分块。远程分块旨在将步骤的处理器部分扩展到单个JVM之外。使用主/从配置,主设备使用常规ItemReader
读取输入。然后通过Spring Integration通道将项目发送给从站进行处理。结果可以写入从站或返回到主站进行写入。重要的是要注意,在这种方法中,主人读取的每个项目都将通过电线进行,因此它可能非常密集,只应考虑处理瓶颈比发送的可能影响更大。消息。您可以在此处的文档中阅读有关远程分块的更多信息:http://docs.spring.io/spring-batch/trunk/reference/html/springBatchIntegration.html#externalizing-batch-process-execution