我用 java 编写了所有微服务。我希望将多个使用者与 Amazon SQS 结合使用,但每个使用者在负载均衡器后面的 AWS 上都有多个实例。
我使用 SNS 作为输入流
我在 SNS 之后使用 SQS 标准队列。
我在 stackoverflow 上发现了同样的问题 ( Using Amazon SQS with multiple consumers )
这个样本是
https://aws.amazon.com/fr/blogs/aws/queues-and-notifications-now-best-friends/
当我阅读 SQS 标准队列文档时,我发现有时会传递多个消息副本。:
每条消息都有一个message_id
。如何检测同一微服务的多个实例是否处理已发送多次的同一消息。我通过在 dynamodb 数据库中注册 message_id
得到了一个想法,但如果这是由同一微服务的多个实例完成的,如何在 get 上锁定(有点像 SELECT FOR UPDATE )?
例如,同一微服务“扫描元数据”的多个实例。
最佳答案
正如您所提到的,标准 SQS 队列有时可以多次传递相同的消息。这是由于 SQS 服务的分布式性质。每条消息都存储在多个服务器上以实现冗余,并且有一个变化,即当您调用 sqs:DeleteMessage
时,其中一个服务器已关闭,因此该消息不会从所有服务器中删除,并且一次失败的服务器重新上线,它不知道您已删除该消息,并且会再次处理该消息。
解决重复消息问题的最简单方法是改用 FIFO 队列,它可以为您提供一次性处理。您可以选择根据内容或发件人生成的唯一 ID 使用重复数据删除。如果选择使用内容去重,当队列在5分钟内收到两条内容相同的消息时。重复数据删除间隔后,该消息将被丢弃。
如果两条消息可以具有相同的内容,但您需要将它们视为不同的消息,则可以根据可传递给 sqs:SendMessage
或 sqs:SendMessageBatch 的 ID 使用重复数据删除
通过 MessageDeduplicationId
参数调用。
在考虑使用 DynamoDB 存储消息处理状态之前,我肯定会检查 FIFO 队列。它会更便宜,并且默认为您提供重复数据删除功能,而无需您实现任何复杂的逻辑。
关于java - 使用 Amazon SQS 的多个消费者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57179002/