如何使用spring集成来消耗sqs队列的消耗

时间:2017-10-20 12:39:49

标签: java spring spring-integration amazon-sqs spring-integration-dsl

我正在尝试设置一个集成流来消耗来自amazon sqs队列的消息,并且到目前为止它的工作正常。但我想调整每分钟或几秒钟的消息数量。例如每分钟20条消息。

这是我的sql监听器bean的定义

    @Bean
    public MessageProducer mySqsMessageDrivenChannelAdapter() {
        SqsMessageDrivenChannelAdapter adapter = new SqsMessageDrivenChannelAdapter(this.amazonSqs, queueName);
        adapter.setMessageDeletionPolicy(SqsMessageDeletionPolicy.ON_SUCCESS);

        adapter.setVisibilityTimeout(TIMEOUT_VISIBILITY);
        adapter.setWaitTimeOut(TIMEOUT_MESSAGE_WAIT);
        adapter.setMaxNumberOfMessages(prefetch);
        adapter.setOutputChannel(processMessageChannel());
        return adapter;
    }

正如您所看到的,我正在设置每次轮询获取的最大邮件数,但是如何设置轮询之间的延迟?

在常规的jms队列中,我可以使用自定义轮询器使用JMS.inboundAdapter,但似乎使用SqsMessageDrivenChannelAdapter我无法设置任何轮询计时器值。

也许我可以使用除SqsMessageDrivenChannelAdapter之外的MessageProducer但是哪一个?

是否可以使用sqs?

设置JMS.inboundAdapter

1 个答案:

答案 0 :(得分:1)

Spring Integration SqsMessageDrivenChannelAdapter是一个消息驱动程序活动组件。它基于Springh Cloud AWS项目中的SimpleMessageListenerContainer,该项目长期运行while()循环以调用AmazonSQS.receiveMessage()。该循环中的逻辑并不太复杂:

try {
    ReceiveMessageResult receiveMessageResult = getAmazonSqs().receiveMessage(this.queueAttributes.getReceiveMessageRequest());
    CountDownLatch messageBatchLatch = new CountDownLatch(receiveMessageResult.getMessages().size());
    for (Message message : receiveMessageResult.getMessages()) {
        if (isQueueRunning()) {
            MessageExecutor messageExecutor = new MessageExecutor(this.logicalQueueName, message, this.queueAttributes);
                 getTaskExecutor().execute(new SignalExecutingRunnable(messageBatchLatch, messageExecutor));
        } else {
           messageBatchLatch.countDown();
        }
    }
    try {
         messageBatchLatch.await();
    } catch (InterruptedException e) {
         Thread.currentThread().interrupt();
    }
} catch (Exception e) {

如您所见,我们在那里创建messageBatchLatch并在循环后等待它。 每条消息都由他们自己的SignalExecutingRunnable处理,countDown()MessageExecutor的末尾。因此,您可能希望在目标服务方法中使用人工Thread.sleep()来实现,以便在SQS轮询之间有更多的间隔。

但我听到了您的要求,我们确实需要添加类似的内容:

/**
 * The sleep interval in milliseconds used in the main loop between shards polling cycles.
 * Defaults to {@code 1000} minimum {@code 250}.
 * @param idleBetweenPolls the interval to sleep between shards polling cycles.
 */
public void setIdleBetweenPolls(int idleBetweenPolls) {
    this.idleBetweenPolls = Math.max(250, idleBetweenPolls);
}

我为KinesisMessageDrivenChannelAdapter做了这个,但是我们必须要求Spring Cloud AWS为SimpleMessageListenerContainer执行此操作。