我正在尝试实施spring集成文件轮询,其中多个服务器独立地从一个公共目录读取并处理该文件。处理文件后,每个文件都将其重命名为.DONE,以便其他人不选择它。在观察到两个文件都被选中后,我使用了nioLocker,如下例所示。但是看起来这是行不通的。让我知道使nioLocker在多服务器环境中可靠的必要步骤。出于其他原因,不能选择单独的调解人(例如zookeepr / mongo等)。
谢谢。
@Bean
public TransactionSynchronizationFactory transactionSynchronizationFactory() {
ExpressionParser parser = new SpelExpressionParser();
ExpressionEvaluatingTransactionSynchronizationProcessor syncProcessor =
new ExpressionEvaluatingTransactionSynchronizationProcessor();
syncProcessor.setAfterCommitExpression(parser.parseExpression("payload.renameTo(new java.io.File(payload.path+'.DONE'))"));
syncProcessor.setAfterRollbackExpression(parser.parseExpression("payload.renameTo(new java.io.File(payload.path+'.DONE'))"));
return new DefaultTransactionSynchronizationFactory(syncProcessor);
}
@Bean
public IntegrationFlow receiveInputFile(@Value("/opt/tomcat/in/test") File in,
@Value(".txt") String pattern,
@Value("${edi.poll.delay.all.edi}") int delay,
@Value("${edi.messages.per.poll.new.order}") int messagesPerPoll) {
//Logging required config for debugging
LOGGER.debug("EDI File pattern :"+pattern);
LOGGER.debug("EDI Delay Seconds :"+delay);
LOGGER.debug("EDI Messages Per Poll :"+messagesPerPoll);
return IntegrationFlows
.from(s -> s.file(in).patternFilter(ServicesConstant.PATTERN_PREFIX + pattern).scanEachPoll(true).nioLocker(),
e -> e.poller(Pollers.fixedDelay(delay).maxMessagesPerPoll(messagesPerPoll)
.transactionSynchronizationFactory(transactionSynchronizationFactory())
.transactional(new PseudoTransactionManager())))
.handle(m -> {
LOGGER.info("Received test file " + m);
LOGGER.info("File path: " +m.getPayload());
LOGGER.info(""+ m.getHeaders().toString());
})
.get();
}
答案 0 :(得分:0)
查看其JavaDocs:
/**
* File locking strategy that uses java.nio. The locks taken by FileChannel are shared with all the threads in a single
* JVM, so this locking strategy <b>does not</b> prevent files being picked up multiple times within the same JVM.
* {@link FileReadingMessageSource}s sharing a Locker will not pick up the same files.
* <p>
* This implementation will acquire or create a {@link FileLock} for the given file. Caching locks might be expensive,
* so this locking strategy is not recommended for scenarios where many files are accessed in parallel.
*
* @author Iwein Fuld
* @author Mark Fisher
* @since 2.0
*/
public class NioFileLocker extends AbstractFileLockerFilter {
在我的实践中,我们确实只有在Windows上才拥有良好的排他文件锁定。
如果我们仅处理单个本地文件系统,那么我不确定“多服务器环境”对您意味着什么。我非常确定,此NIO锁定对共享的网络目录无效。
如果您不能使用任何共享的持久性存储进行文件过滤,建议您使用真正的共享FileSystemPersistentAcceptOnceFileListFilter
实现来研究MetadataStore
,让所有服务器协商并确保该文件尚未被其他服务器处理。