Spring Integration在事务中将消息发送到Executor

时间:2018-06-20 10:13:08

标签: java spring-integration spring-integration-http

我有大量来自CSV文件的消息,然后将其发送到限速API。我正在使用由数据库通道消息存储支持的队列通道,以使消息在处理时持久。我想尽可能接近速率限制,所以我需要跨多个线程向API发送消息。

我对如何工作的想法是,读取数据库,查看可用的消息,然后将每个消息委托给要在事务中处理的线程之一。

但是我还没有做到这一点,我要做的是拥有一个事务性轮询器,该轮询器具有N个线程的线程池,固定速率为5秒,每次轮询的最大消息数为10(比5秒内可以处理的东西还多)...可以正常工作,但是当没有太多消息等待时(例如,如果有10条消息,它们将由一个线程处理)会出现问题,这不是实际上将是一个问题,因为我们将有1000条消息。但是从概念上讲,它似乎比我认为的工作要复杂。

我可能没有很好地解释这一点,但是当消息快速传入但输出缓慢时,似乎是一个常见问题?

1 个答案:

答案 0 :(得分:0)

您的解决方案确实是正确的,但是您需要考虑不要将消息转移到Exectuor中,因为那样您会跳出事务边界。

在同一线程中处理了10条消息的事实恰好是实现细节,它看起来像这样:

AbstractPollingEndpoint.this.taskExecutor.execute(() -> {
            int count = 0;
            while (AbstractPollingEndpoint.this.initialized
                    && (AbstractPollingEndpoint.this.maxMessagesPerPoll <= 0
                    || count < AbstractPollingEndpoint.this.maxMessagesPerPoll)) {
                try {
                    if (!Poller.this.pollingTask.call()) {
                        break;
                    }
                    count++;
                }

因此,我们在同一线程中轮询消息,直到maxMessagesPerPoll

要使其真正更并行并且仍保持事务不丢失消息,您需要考虑使用fixedRate

/**
 * Specify whether the periodic interval should be measured between the
 * scheduled start times rather than between actual completion times.
 * The latter, "fixed delay" behavior, is the default.
 */
public void setFixedRate(boolean fixedRate)

并增加TaskScheduler用于轮询的线程数量。 您可以执行以下操作:声明一个名称为ThreadPoolTaskScheduler的{​​{1}} bean,以覆盖池值为IntegrationContextUtils.TASK_SCHEDULER_BEAN_NAME的默认bean。或使用全局属性仅覆盖默认值10中的池大小:https://docs.spring.io/spring-integration/docs/5.0.6.RELEASE/reference/html/configuration.html#global-properties