Amazon SQS 处理侦听器的更好方法

Blu*_*ace 3 multithreading amazon-sqs amazon-web-services

我有一个 SQS 队列,其中有很多消息(通常为数千条)。目前,我有多个侦听器(由从同一源创建的线程创建),每个侦听器侦听队列并接收消息。一旦侦听器从队列接收到消息,该侦听器就会从队列中删除该消息。只有从队列中删除消息后才会处理该消息。我的可见性超时为 30 秒。

我没有使用任何锁或任何东西来处理重复项,因为我在接收后立即从队列中删除消息。到目前为止我还没有看到口是心非的案例,但我只是担心可能会发生。

现在的问题是,哪种方法更好,以这种方式拥有多个侦听器,还是在单个线程中侦听队列,然后启动新线程来处理收到的每条消息?

Joh*_*ein 6

首先,有必要了解消息不可见超时的概念。

当从 Amazon SQS 队列(例如,通过您的线程)检索消息时,该消息在 Amazon SQS 中被标记为不可见。最佳实践是让您的线程处理该消息,然后在完成消息处理后删除该消息。这样,如果线程失败,消息将自动再次在队列中可见,并且另一个线程可以处理它。

对于当前的应用程序设计,如果线程失败,则消息将丢失并且不会重试。您应该考虑更改代码以仅消息处理后将其删除。

建议使用多个线程来处理消息,因为并行处理消息将允许更高的消息吞吐量。这也是一个更简单的设计,简单总是最好的。让一个进程检索消息然后启动线程来处理消息的另一种想法更加复杂,并且不会带来任何好处。

Amazon SQS 队列有时可能会多次返回同一消息。这种情况很少见,但也有可能发生。多线程设计可能会导致这种情况比单线程设计发生更多,因为多个线程可能同时检索相同的消息。然而,在单线程模型中它仍然可能发生

如果您担心处理同一消息两次,请考虑使用FIFO 队列(目前并非在每个 AWS 区域都可用)。这将保证每条消息仅被接收一次。或者,您的代码需要检查特定消息是否已被处理(例如通过检查数据库)。

多线程设计还允许您通过让多个系统(甚至跨多个可用区)处理消息来进行水平扩展,而单线程设计存在单点故障并且可扩展性较差。