配置任务调度器

在 Spring Integration 中,ApplicationContext 扮演着消息总线的核心角色,您只需要考虑几个配置选项。首先,您可能希望控制核心的 TaskScheduler 实例。可以通过提供一个名为 taskScheduler 的 bean 来实现。这也定义为一个常量,如下所示

IntegrationContextUtils.TASK_SCHEDULER_BEAN_NAME

默认情况下,Spring Integration 依赖于 ThreadPoolTaskScheduler 实例,如 Spring Framework 参考手册的任务执行和调度部分所述。默认的 TaskScheduler 会自动启动一个包含十个线程的线程池,但请参阅全局属性。如果您提供自己的 TaskScheduler 实例,则可以将其 'autoStartup' 属性设置为 false 或提供自己的线程池大小值。

当轮询消费者在其配置中提供明确的任务执行器引用时,处理器方法的调用会在该执行器的线程池中发生,而不是在主调度器线程池中。但是,如果端点的轮询器没有提供任务执行器,则它将由主调度器的线程之一调用。

不要在轮询器线程上运行长时间运行的任务。请改用任务执行器。如果有很多轮询端点,除非增加线程池大小,否则可能导致线程饥饿。此外,轮询消费者的默认 receiveTimeout 为一秒。由于轮询器线程会阻塞这段时间,我们建议在存在大量此类端点时使用任务执行器,同样是为了避免饥饿。或者,可以减小 receiveTimeout
如果端点的输入通道是基于队列(即可轮询的)通道之一,则该端点是一个轮询消费者。事件驱动消费者是指输入通道具有分发器而不是队列(换句话说,它们是可订阅的)的端点。这类端点没有轮询器配置,因为它们的处理器是直接调用的。

在 JEE 容器中运行时,您可能需要使用 Spring 的 TimerManagerTaskScheduler,如此处所述,而不是默认的 taskScheduler。为此,请定义一个具有适合您环境的 JNDI 名称的 bean,示例如下

<bean id="taskScheduler" class="org.springframework.scheduling.concurrent.DefaultManagedTaskScheduler">
    <property name="jndiName" value="tm/MyTimerManager" />
    <property name="resourceRef" value="true" />
</bean>
当在应用程序上下文中配置了自定义的 TaskScheduler(例如上面提到的 DefaultManagedTaskScheduler)时,建议为其提供一个 MessagePublishingErrorHandlerintegrationMessagePublishingErrorHandler bean),以便能够将异常作为发送到错误通道的 ErrorMessage`s 处理,就像框架提供的默认 `TaskScheduler bean 那样。

另请参阅错误处理以获取更多信息。