使用弹簧云监听AWS SQS队列,如下所示:
@SqsListener(value = "${queue.name}", deletionPolicy = SqsMessageDeletionPolicy.ON_SUCCESS)
public void queueListener(String message, @Headers Map<String, Object> sqsHeaders) {
// code
}
Spring config:
<aws-messaging:annotation-driven-queue-listener
max-number-of-messages="10" wait-time-out="20" visibility-timeout="3600"
amazon-sqs="awsSqsClient" />
AwsSqsClient:
@Bean
public com.amazonaws.services.sqs.AmazonSQSAsyncClient awsSqsClient() {
ExecutorService executorService = Executors.newFixedThreadPool(10);
return new AmazonSQSAsyncClient(new DefaultAWSCredentialsProviderChain(), executorService);
}
这很好用。
在SQS客户端中配置了10个线程来处理这些消息,如上所示。这也很好,在任何时候都可以处理最多10条消息。
问题是,我无法找到控制轮询间隔的方法。默认情况下,一旦所有线程都空闲,弹出轮询。
即。考虑以下示例
与此同时,大约有25条消息被送到队列。在完成之前传递的所有3条消息之前,Spring不会轮询队列。基本上如上面的例子,春季民意调查仅在20分钟之后,尽管有7个线程仍然是免费的!
知道我们如何控制这次投票吗?即如果有任何线程空闲,则应该开始轮询,并且不应该等到所有线程都空闲
答案 0 :(得分:0)
您的侦听器可以将消息加载到您的Spring应用程序中,并将它们与Acknowledgment和Visibility对象一起提交到另一个线程池(如果您想同时控制两者)。 将消息提交到此线程池后,您的侦听器可以加载更多数据。您可以通过调整线程池设置来控制并发性。
您的侦听器的方法签名将类似于以下内容:
@SqsListener(value = "${queueName}", deletionPolicy = SqsMessageDeletionPolicy.NEVER)
public void listen(YourCustomPOJO pojo,
@Headers Map<String, Object> headers,
Acknowledgment acknowledgment,
Visibility visibility) throws Exception {
...... Send pojo to worker thread and return
然后,工作线程将确认处理成功
acknowledgment.acknowledge().get();
确保将消息可见性设置为大于最大处理时间的值(使用某些超时来限制执行时间)。