我有一个Spring Boot / Spring Integration应用程序正在运行,它在Spring Integration中使用@Poller,并在一个几乎不相关的类中的另一个方法上使用@Scheduled。@Poller用于轮询FTP服务器以获取新文件。然而,我发现似乎@Poller以某种方式干扰了我的@Scheduled方法。
@Poller有maxMessagesPerPoll = -1,所以它可以处理尽可能多的文件。但是,当我第一次启动我的应用程序时,FTP服务器上有100多个文件,所以它将处理所有这些文件。我发现,如果正在处理这些文件,那么@Scheduler将完全停止触发。
例如,如果我将@Scheduled设置为每毫秒触发一次fixedDelay = 1,然后启动应用程序,则@Scheduled方法将触发几次,直到@Poller触发并开始处理消息,此时我的@Scheduled方法完全停止触发。我假设只是有一些任务队列正在由@Poller填充,所以我只需要等待处理所有消息,但是即使在@Poller完全完成并处理了所有文件之后,@Scheduled方法仍然根本不会触发。
我的想法是,也许有一些任务队列正在被@Poller填充,这破坏了我的@Scheduled方法,但如果是这样的话,我仍然看不到任何方法可以使用单独的任务队列来处理不同的方法,或者任何其他可能的选项来自定义或修复这个问题。
有没有人知道我的@Scheduled方法可能发生了什么,我该如何修复这个问题?
@Poller:
@Bean
@InboundChannelAdapter(channel = "ftpChannel", poller = @Poller(cron = "0/5 * * ? * *", maxMessagesPerPoll = "-1"))
public MessageSource<InputStream> myMessageSource() {
//Build my message source
return messageSource;
}@Scheduled
@Scheduled(fixedDelay = 6000)
public void myScheduledMethod(){
//Do Stuff
}发布于 2020-03-17 05:51:09
它们对它们的调度程序taskScheduler使用相同的bean名称。
只有当您有10个或更多的轮询器时,这才应该是问题( Spring Integration配置的默认调度程序bean的池大小缺省为10 )。一个常见的错误是有许多队列通道(缺省情况下,这些通道一次只能占用调度程序线程一秒钟)。
如果您只有一个轮询器,并且队列通道不多,我无法解释为什么会出现线程匮乏。
您可以增加池大小-请参见Configuring the Task Scheduler。
或者,您可以在ScheduledAnnotationBeanPostProcessor中使用不同的调度程序。
发布于 2020-05-28 03:33:23
由于已经pointed out,该问题被链接到具有相同名称的任务调度器,尽管即使轮询器少于10个也可能发生该问题。Spring Boot自动配置为调度器提供默认池大小为1的调度器,该调度器的注册可能发生在Spring Integration提供的taskScheduler注册之前。
通过Spring Integration properties配置任务调度器没有任何帮助,因为这个bean根本不会注册。但是,提供自己的TaskScheduler实例并调整池大小、通过spring.task.scheduling.pool.size属性更改自动配置的调度器的池大小或排除TaskSchedulingAutoConfiguration可以解决这个问题。
https://stackoverflow.com/questions/60713284
复制相似问题