如何使nodejs服务器监听AWS SQS?

16
在我详细解释问题之前,先告诉你我的当前方法。
我有一个运行setInterval()的js脚本。每个时间间隔,我都会调用SQS来获取队列中的消息。如果有消息,则进行处理。
因此,它将无限运行,直到我终止进程。
我以前也构建过一个node服务器(使用nodejs.org上的示例)。
所以,我想知道是否有一种方式,如果SQS中有新消息,它可以触发一个事件并处理该消息,而不是定期运行setInterval()?
4个回答

10

这个问题已经超过2年了..但是有一种比更改轮询间隔时间更好的方法。 可以将队列的"接收消息等待时间"设置为最大值20秒,这样可以进行持续轮询,但在队列为空时每分钟只会发出3个请求。当队列中有数据时,响应会立即返回。


现在这被称为 WaitTimeSeconds。 - Daniel Viglione

8

不行。你必须从SQS请求消息。

如果你真的需要推送通知,请看看SNS。如果您想在将消息添加到队列后提示您的服务器轮询SQS,那么SNS效果很好。


1
当您拥有一组ECS任务时,这似乎无法很好地工作。只有一个任务将开始轮询SQS,因为您必须订阅URL端点,而负载均衡器只会将请求转发到其中一个任务。 - Daniel Viglione

7
您可以使用SQS长轮询来实现此操作。长轮询通过允许Amazon SQS等待队列中有消息可用后再发送响应,从而减少了空响应的数量。这也将显著降低SQS的成本。
为了使这个过程更加容易,有一个叫做sqs-consumer的优秀库。它只需要您定义一个接收SQS消息的函数,并在处理完消息时调用回调即可。
const Consumer = require('sqs-consumer');

const app = Consumer.create({
  queueUrl: 'https://sqs.eu-west-1.amazonaws.com/account-id/queue-name',
  handleMessage: (message, done) => {
    // do some work with `message`
    done();
  }
});

app.on('error', (err) => {
  console.log(err.message);
});

app.start();

在幕后,它已经使用了上述长轮询技术。


3

SQS不提供通知功能,但如果SQS中有新消息,您可以让创建该消息的任何内容也触发node.js并在几分钟内开始轮询。您可能无法控制队列中的内容,但如果可以,我建议也将其触发您的node.js以开始轮询队列。

如果您担心轮询会导致成本问题,您可以像我一样动态更改轮询时间。我的SQS队列每5秒钟轮询一次。如果节点检测到消息,则立即将轮询时间降低至200毫秒,持续几秒钟。如果未在队列中检测到消息,则每个空请求都会减慢50毫秒,直到再次达到5秒轮询。

第一个请求将会很慢,这是您可能无法处理的。为了解决这个问题,我让轮询时间每隔几分钟随机加速。通过几个节点进行轮询,响应时间通常非常快。


4
若您能够提供动态轮询时间的工作代码示例,将非常不错。 - Mark

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接