我们正在混合 spring-integration 和 spring-boot 的调度功能,使用:
@SpringBootApplication
@EnableIntegration
@IntegrationComponentScan
@EnableConfigurationProperties
@EnableScheduling
public class MyApplication {
...
}
@EnableScheduling
创建一个名为“taskScheduler”的 bean,然后由 spring-integration 使用:
public abstract class IntegrationContextUtils {
public static final String TASK_SCHEDULER_BEAN_NAME = "taskScheduler";
...
}
private void registerTaskScheduler() {
if (!this.beanFactory.containsBean(IntegrationContextUtils.TASK_SCHEDULER_BEAN_NAME)) {
...
this.registry.registerBeanDefinition(IntegrationContextUtils.TASK_SCHEDULER_BEAN_NAME, scheduler);
}
}
问题是,spring-integration的默认poolSize是10(当我们遇到饥饿时需要这个值),而spring-boot的默认池大小是1(我们还需要避免调度进程中的并发)。
问题:
谢谢您的回答
行为和逻辑是正确的。从 Spring Boot 的角度来看,配置约定的期望也是正确的。只是您错过了
@EnableScheduling
不是 Spring Boot 功能,而是 Spring Framework 原生功能:https://docs.spring.io/spring-framework/docs/current/reference/html/integration.html#scheduling 。 Spring Boot 刚刚给了我们额外的自由来配置一些关于此事的 bean。所以,我们只需要依赖它的自动配置即可。
如果自动配置不符合您的要求,您始终可以提供自己的配置并在需要时覆盖。
看看 Spring Boot 中的
@EnableScheduling
、它的 @Scheduled
钩子和适当的 TaskSchedulingAutoConfiguration
,要同时覆盖您想让 Spring Integration 满意的任何内容并不容易。因此,我们应该采取相反的方向,并真正覆盖 Spring Integration 端点的 Scheduler
。在每个使用 poller
的地方,您还需要配置自定义 Scheduler
,而不是自动配置。
在我们的例子中,解决此问题的最简单方法是覆盖默认调度程序池大小:
spring.task.scheduling.pool.size=16
当然需要注意的是,您无法通过这种方式避免计划进程的并发。当然,如果您需要的话,这取决于您的用例,但通常只要您可以部署多个服务实例,单线程池无论如何都不会帮助您。
另一个潜在问题是调度程序仍然可能占用所有线程并阻止您的集成流程,反之亦然。如果这是您的用例中的真正问题,您必须按照 Artem 的建议配置单独的线程池。