Mak*_*kky 6 java spring-integration spring-integration-dsl
我已经用任务执行器设置了文件轮询器
ExecutorService executorService = Executors.newFixedThreadPool(10);
LOG.info("Setting up the poller for directory {} ", finalDirectory);
StandardIntegrationFlow standardIntegrationFlow = IntegrationFlows.from(new CustomFileReadingSource(finalDirectory),
c -> c.poller(Pollers.fixedDelay(5, TimeUnit.SECONDS, 5)
.taskExecutor(executorService)
.maxMessagesPerPoll(10)
.advice(new LoggerSourceAdvisor(finalDirectory))
))
//move file to processing first processing
.transform(new FileMoveTransformer("C:/processing", true))
.channel("fileRouter")
.get();
Run Code Online (Sandbox Code Playgroud)
正如所见,我已将threadpool每次轮询设置为固定的 10 条消息和最多 10 条消息。如果我放了 10 个文件,它仍然会一一处理。这里有什么问题?
* 更新 *
尽管我现在有其他问题,但在加里的回答之后它工作得很好。
我已经像这样设置了我的轮询器
setDirectory(new File(path));
DefaultDirectoryScanner scanner = new DefaultDirectoryScanner();
scanner.setFilter(new AcceptAllFileListFilter<>());
setScanner(scanner);
Run Code Online (Sandbox Code Playgroud)
使用的原因是AcceptAll因为同一个文件可能会再次出现,这就是我先移动文件的原因。但是当我启用线程执行器时,多个线程正在处理同一个文件,我假设是因为AcceptAllFile
如果我更改AcceptOnceFileListFilter它可以工作,但是再次出现的同一个文件将不会再次被拾取!可以做些什么来避免这个问题?
问题/错误
在课堂上AbstractPersistentAcceptOnceFileListFilter我们有这个代码
@Override
public boolean accept(F file) {
String key = buildKey(file);
synchronized (this.monitor) {
String newValue = value(file);
String oldValue = this.store.putIfAbsent(key, newValue);
if (oldValue == null) { // not in store
flushIfNeeded();
return true;
}
// same value in store
if (!isEqual(file, oldValue) && this.store.replace(key, oldValue, newValue)) {
flushIfNeeded();
return true;
}
return false;
}
}
Run Code Online (Sandbox Code Playgroud)
现在,例如,如果我设置了 max per poll 5 并且有两个文件,那么两个线程可能会选择相同的文件。
假设我的代码在阅读后移动文件。
但是另一个线程访问了该accept方法
如果文件不存在,那么它会将 lastModified 时间返回为 0 并且它将返回 true。
这会导致问题,因为文件不存在。
如果它是 0 那么它应该返回 false 因为文件不再存在。
当您向轮询器添加任务执行器时;所要做的就是调度程序线程将轮询任务交给线程池中的一个线程;这maxMessagesPerPoll是投票任务的一部分。轮询器本身每 5 秒只运行一次。为了得到你想要的,你应该在流中添加一个执行器通道......
@SpringBootApplication
public class So53521593Application {
private static final Logger logger = LoggerFactory.getLogger(So53521593Application.class);
public static void main(String[] args) {
SpringApplication.run(So53521593Application.class, args);
}
@Bean
public IntegrationFlow flow() {
ExecutorService exec = Executors.newFixedThreadPool(10);
return IntegrationFlows.from(() -> "foo", e -> e
.poller(Pollers.fixedDelay(5, TimeUnit.SECONDS)
.maxMessagesPerPoll(10)))
.channel(MessageChannels.executor(exec))
.<String>handle((p, h) -> {
try {
logger.info(p);
Thread.sleep(10_000);
}
catch (InterruptedException e1) {
Thread.currentThread().interrupt();
}
return null;
})
.get();
}
}
Run Code Online (Sandbox Code Playgroud)
编辑
这对我来说可以...
@Bean
public IntegrationFlow flow() {
ExecutorService exec = Executors.newFixedThreadPool(10);
return IntegrationFlows.from(Files.inboundAdapter(new File("/tmp/foo")).filter(
new FileSystemPersistentAcceptOnceFileListFilter(new SimpleMetadataStore(), "foo")),
e -> e.poller(Pollers.fixedDelay(5, TimeUnit.SECONDS)
.maxMessagesPerPoll(10)))
.channel(MessageChannels.executor(exec))
.handle((p, h) -> {
try {
logger.info(p.toString());
Thread.sleep(10_000);
}
catch (InterruptedException e1) {
Thread.currentThread().interrupt();
}
return null;
})
.get();
}
Run Code Online (Sandbox Code Playgroud)
和
2018-11-28 11:46:05.196 INFO 57607 --- [pool-1-thread-1] com.example.So53521593Application:/tmp/foo/test1.txt
2018-11-28 11:46:05.197 INFO 57607 --- [pool-1-thread-2] com.example.So53521593Application:/tmp/foo/test2.txt
与 touch test1.txt
2018-11-28 11:48:00.284 INFO 57607 --- [pool-1-thread-3] com.example.So53521593Application:/tmp/foo/test1.txt
编辑1
同意 - 转载此...
@Bean
public IntegrationFlow flow() {
ExecutorService exec = Executors.newFixedThreadPool(10);
return IntegrationFlows.from(Files.inboundAdapter(new File("/tmp/foo")).filter(
new FileSystemPersistentAcceptOnceFileListFilter(new SimpleMetadataStore(), "foo")),
e -> e.poller(Pollers.fixedDelay(5, TimeUnit.SECONDS)
.maxMessagesPerPoll(10)))
.channel(MessageChannels.executor(exec))
.<File>handle((p, h) -> {
try {
p.delete();
logger.info(p.toString());
Thread.sleep(10_000);
}
catch (InterruptedException e1) {
Thread.currentThread().interrupt();
}
return null;
})
.get();
}
Run Code Online (Sandbox Code Playgroud)
和
2018-11-28 13:22:23.689 INFO 75681 --- [pool-1-thread-1] com.example.So53521593Application:/tmp/foo/test1.txt
2018-11-28 13:22:23.690 INFO 75681 --- [pool-1-thread-2] com.example.So53521593Application:/tmp/foo/test2.txt
2018-11-28 13:22:23.690 INFO 75681 --- [pool-1-thread-3] com.example.So53521593Application:/tmp/foo/test1.txt
2018-11-28 13:22:23.690 INFO 75681 --- [pool-1-thread-4] com.example.So53521593Application:/tmp/foo/test2.txt
| 归档时间: |
|
| 查看次数: |
1704 次 |
| 最近记录: |