Spring SkipListener处理无序事件
我有一个spring批处理作业,它使用Spring SkipListener处理无序事件,spring,logging,batch-processing,spring-batch,error-logging,Spring,Logging,Batch Processing,Spring Batch,Error Logging,我有一个spring批处理作业,它使用SkipListener将任何错误输出到错误文件。在一个步骤(读取、处理、写入)中可能会发生各种类型的错误,跳过侦听器知道如何处理这些错误。这很好用 但是,我注意到错误被无序地写入输出。这意味着处理器的错误似乎是在读卡器的任何错误之前写入的 这引起了我极大的关注,因为我需要按照读取错误的相同顺序写入错误(您会注意到跳过限制非常高,提交间隔为1,因此这不是分块的问题)。就所有实际目的而言,这是一项非常平凡的工作,不会让我相信是实际的读卡器或处理器中的某些东西导
SkipListener
将任何错误输出到错误文件。在一个步骤(读取、处理、写入)中可能会发生各种类型的错误,跳过侦听器知道如何处理这些错误。这很好用
但是,我注意到错误被无序地写入输出。这意味着处理器的错误似乎是在读卡器的任何错误之前写入的
这引起了我极大的关注,因为我需要按照读取错误的相同顺序写入错误(您会注意到跳过限制非常高,提交间隔为1,因此这不是分块的问题)。就所有实际目的而言,这是一项非常平凡的工作,不会让我相信是实际的读卡器或处理器中的某些东西导致了这种情况
这整件事让我困惑不解;这很奇怪。我希望有人能给我指出解决这个问题的正确方向。即使答案是“事情就是这样,你无法改变。”
以下是作业定义的相关部分:
<job id="devJob" xmlns="http://www.springframework.org/schema/batch">
... some steps ...
<step id="devProcessStep" next="REMOVED_FOR_SO">
<tasklet>
<chunk reader="devFileReader" processor="devItemProcessor" writer="devOutputWriter" commit-interval="1" skip-limit="999999">
<streams>
<stream ref="devInputReaderStream" />
<stream ref="devErrorOutputWriterStream" />
<stream ref="devOutputWriterStream" />
</streams>
<skippable-exception-classes>
<include class="org.springframework.batch.item.ItemReaderException"/>
... others, but removed since it doesn't matter for this question ...
<exclude class="org.springframework.batch.item.NonTransientResourceException"/>
</skippable-exception-classes>
</chunk>
<listeners>
<listener ref="devSkipListener" />
</listeners>
</tasklet>
</step>
... more steps ...
</job>
...
<bean id="devSkipListener" class="you.have.to.guess.DevSkipListener" scope="job">
<property name="writer" ref="devErrorOutputWriterStream" />
... other properties that are based on job parameters ...
</bean>
...
<bean id="devErrorOutputWriter"
class="org.springframework.batch.item.file.FlatFileItemWriter" scope="job">
... a bunch of properties based on job parameters etc.
</bean>
简而言之,
SkipListener
的合同并不保证要处理的项目的顺序。每次跳过只调用侦听器上的方法一次。您是否介意将我指向源代码的方向,在那里我可以看到当前的实现是如何完成的,并确定是否有其他途径可以确保遵守错误顺序?我非常乐意贡献这个补丁。遗憾的是,事实并非如此,因为我怀疑我不是唯一一个需要与输入顺序相同的输出的人。请查看FaultTolerantChunkProvider
,了解与读取相关的跳过,以及FaultTolerantChunkProcessor
了解与处理器/写入程序相关的跳过。如果您确实提交了PR,请确保重新运行所有单元测试。这些课程的变化非常敏感。当然,谢谢。我不确定什么时候我会有足够的空闲时间来做这件事,但我很感谢你的快速回复和补充信息。我想回馈给这样一个令人惊叹的项目,我希望这一贡献具有同样的质量。再次感谢迈克尔,感谢你的辛勤工作!
package you.have.to.guess
// bunch of imports (removed for SO)
class DevSkipListener implements SkipListener {
private static def log = LogFactory.getLog(this)
ItemWriter writer
// some other properties, not important
@Override
void onSkipInRead(Throwable e) {
log.debug("Skip error in read", e)
// some stuff here to figure out the lines
writer.write(lines)
}
@Override
void onSkipInProcess(Object item, Throwable e) {
log.debug("Skip error in process", e)
// some stuff here to figure out the lines
writer.write(lines)
}
@Override
void onSkipInWrite(Object item, Throwable e) {
log.debug("Skip error in write", e)
// some stuff here to figure out the lines
writer.write(lines)
}
}