将Amazon SQS与多个消费者一起使用

时间:2015-05-18 06:40:40

标签: amazon-web-services amazon-sqs microservices event-based-programming

我有一个基于服务的应用程序,它使用具有多个队列和多个消费者的Amazon SQS。我这样做是为了实现基于事件的体系结构并解耦所有服务,其中不同的服务对其他系统的状态变化做出反应。例如:

  • 注册服务
    • 发布活动'注册 - 新'当新用户注册时。
  • 用户服务
    • 发出活动'用户更新'用户更新时。
  • 搜索服务
    • 从队列中读取' registration-new'并在搜索中索引用户。
    • 从队列中读取'用户更新的'并在搜索中更新用户。
  • 指标服务
    • 来自' registration-new'排队并发送到Mixpanel。
    • 从队列中读取'用户更新的'并发送给Mixpanel。

我遇到了很多问题:

  • 进行轮询时可以多次接收消息。我可以设计很多系统是幂等的,但是对于某些服务(例如度量服务)来说会更困难。
  • 需要在SQS中从队列中手动删除消息。我曾想过实现一个"消息处理服务"在所有服务都收到消息时处理消息的删除(每个服务在处理消息后都会发出消息确认的事件)。

我想我的问题是:我应该使用哪些模式来确保我可以在SQS中为单个队列拥有多个使用者,同时确保消息也可以可靠地传递和删除。谢谢你的帮助。

3 个答案:

答案 0 :(得分:37)

我认为你做错了。

在我看来,你正在使用相同的队列来做多个不同的事情。您最好将单个队列用于单一目的。

而不是将一个事件放入'registration-new'队列,然后让两个不同的服务轮询该队列,并且两个人都需要读取该消息并且两者都做了与它不同的事情(然后需要一个假设的第三个进程)在其他2个消息处理完之后删除该消息。)

一个队列应该用于一个目的。

  • 创建'index-user-search'队列和'send to mixpanels'队列, 所以搜索服务从搜索队列中读取,为用户编制索引 并立即删除该消息。

  • mixpanel-service从mix-panels队列中读取,处理
    消息并删除消息。

注册服务现在将其发送到两个队列,而不是向单个队列发出“registration-new”。

为了更好地做到这一步,在这里添加SNS并让注册服务向'registration-new'主题(不是队列)发出SNS消息,然后订阅我上面提到的两个队列,该主题采用“扇出”模式。

https://aws.amazon.com/blogs/aws/queues-and-notifications-now-best-friends/

两个队列都将收到消息,但您只将其加载到SNS中一次 - 如果在路上第三个不相关的服务还需要处理'registration-new'事件,您还要创建另一个队列并订阅该主题 - 它可以在没有依赖关系的情况下运行,也可以知道其他服务正在做什么 - 这就是目标。

答案 1 :(得分:2)

队列的多个使用者的主要用例是scaling-out

Visibility Timeout是允许多个使用者使用的机制,它使使用者有时间处理和删除消息,而不会被另一个使用者同时使用。

要解决“标准队列”的"At-Least-Once Delivery"属性, 消费服务应为idemptotent。 如果无法实现,则一种可能的解决方案是使用FIFO queues,但是此模式的消息传递速率有限,并且为not compatible with SNS subscription

答案 2 :(得分:0)

他们甚至还提供了有关如何使用SNS + SQS组合创建扇出场景的教程。

https://aws.amazon.com/getting-started/tutorials/send-fanout-event-notifications/

可惜它不支持FIFO队列,因此您必须小心处理乱序消息。

如果他们有一个一致的哈希解决方案,以便在尊重消息顺序的同时拥有多个竞争用户,那将是很好的选择。