【问题标题】:Multiple Consumers with Amazon SQS使用 Amazon SQS 的多个消费者
【发布时间】:2019-12-02 09:01:58
【问题描述】:

我用 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)?

例如同一微服务“扫描元数据”的多个实例。

【问题讨论】:

    标签: java amazon-web-services amazon-sqs amazon-sns


    【解决方案1】:

    正如您所提到的,标准 SQS 队列有时可以多次传递相同的消息。这是由于 SQS 服务的分布式特性。每条消息都存储在多个服务器上以实现冗余,并且当您调用sqs:DeleteMessage 时,其中一个服务器已关闭,因此该消息不会从所有服务器中删除,并且一旦发生故障的服务器重新上线,它不知道你已经删除了这条消息,它会被再次处理。

    解决重复消息问题的最简单方法是切换到使用 FIFO 队列,它为您提供仅一次处理。您可以根据发件人生成的内容或唯一 ID 选择使用重复数据删除。如果选择使用重复内容删除,当队列在 5 分钟内收到两条内容相同的消息时。重复数据删除间隔,消息将被丢弃。

    如果两条消息可以具有相同的内容,但您需要将它们视为不同的消息,则可以使用基于 ID 的重复数据删除,您可以通过 MessageDeduplicationId 参数传递给 sqs:SendMessagesqs:SendMessageBatch 调用。

    在考虑使用 DynamoDB 存储消息处理状态之前,我肯定会检查 FIFO 队列。它会更便宜,而且默认情况下会为您提供重复数据删除功能,而无需您实现任何复杂的逻辑。

    【讨论】:

    • 此外,根据用例,偶尔的消息重复实际上也可以。例如,如果将图像大小调整两次,则会浪费一点处理能力,但这可能比去重更便宜。
    • 重要提示:Amazon SNS 目前与 FIFO 队列不兼容。 docs.aws.amazon.com/AWSSimpleQueueService/latest/…
    • 我不知道这个限制。在这种情况下,我仍然会使用 FIFO 队列,但不是使用 SNS 来扇出这些消息,而是可能会在应用程序中执行 - 调用多个 sqs:SendMessages,每个 SQS 端点一个。
    • @MatusDubrava,如果我仍然使用 FIFO 队列,而不是使用 SNS 来部署这些消息,我可能会在应用程序中通过调用多个 sqs 来完成,我的微服务。 使用队列的目的正是为了消除微服务之间的强耦合。
    • 我写了 "我在 SNS 之后使用 SQS 标准队列" 并且在前面的两个模式中,很明显它是以 SNS 作为入口点
    猜你喜欢
    • 2016-07-01
    • 2016-09-25
    • 1970-01-01
    • 2023-02-17
    • 2016-07-01
    • 2019-05-01
    • 2020-10-21
    • 2015-07-29
    相关资源
    最近更新 更多