我有大量来自CSV文件的消息,然后将其发送到限速API。我正在使用由数据库通道消息存储支持的队列通道,以使消息在处理时持久。我想尽可能接近速率限制,所以我需要跨多个线程向API发送消息。
我对如何工作的想法是,读取数据库,查看可用的消息,然后将每个消息委托给要在事务中处理的线程之一。
但是我还没有做到这一点,我要做的是拥有一个事务性轮询器,该轮询器具有N个线程的线程池,固定速率为5秒,每次轮询的最大消息数为10(比5秒内可以处理的东西还多)...可以正常工作,但是当没有太多消息等待时(例如,如果有10条消息,它们将由一个线程处理)会出现问题,这不是实际上将是一个问题,因为我们将有1000条消息。但是从概念上讲,它似乎比我认为的工作要复杂。
我可能没有很好地解释这一点,但是当消息快速传入但输出缓慢时,似乎是一个常见问题?
答案 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