Amazon web services 对多个消费者使用Amazon SQS

Amazon web services 对多个消费者使用Amazon SQS,amazon-web-services,amazon-sqs,microservices,event-based-programming,Amazon Web Services,Amazon Sqs,Microservices,Event Based Programming,我有一个基于服务的应用程序,它使用AmazonSQS,具有多个队列和多个消费者。我这样做是为了实现一个基于事件的体系结构并解耦所有服务,其中不同的服务对其他系统状态的变化做出反应。例如: 注册服务: 当新用户注册时,发出事件“注册新” 用户服务: 更新用户时发出事件“用户已更新” 搜索服务: 从队列“registration new”(注册新)读取数据,并为搜索中的用户编制索引 读取队列“用户已更新”并更新搜索中的用户 度量服务: 从“注册新”队列读取并发送到Mixpanel 读

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

  • 注册服务
    • 当新用户注册时,发出事件“注册新”
  • 用户服务
    • 更新用户时发出事件“用户已更新”
  • 搜索服务
    • 从队列“registration new”(注册新)读取数据,并为搜索中的用户编制索引
    • 读取队列“用户已更新”并更新搜索中的用户
  • 度量服务
    • 从“注册新”队列读取并发送到Mixpanel
    • 读取队列“用户已更新”并发送到Mixpanel
我有很多问题:

  • 在进行轮询时,可以多次接收消息。我可以将许多系统设计为幂等的,但对于某些服务(如metrics服务),这将非常困难
  • 需要从SQS中的队列中手动删除消息。我曾想过实现一个“消息处理服务”,当所有服务都接收到消息时处理消息的删除(每个服务在处理消息后都会发出一个“消息确认”事件)

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

我认为你做错了

在我看来,您正在使用同一队列来执行多个不同的操作。您最好将单个队列用于单个目的

而不是将一个事件放入“registration new”(注册新)队列,然后让两个不同的服务轮询该队列,两个服务都需要读取该消息并对其执行不同的操作(然后需要第三个进程,该进程应该在其他两个处理完该消息后删除该消息)

一个队列应用于一个目的

  • 创建“索引用户搜索”队列和“发送到混合面板”队列, 因此,搜索服务从搜索队列中读取数据,为用户编制索引 并立即删除该消息

  • mixpanel服务从mix panels队列读取数据,并处理
    并删除该消息

注册服务不再向单个队列发送“新注册”,而是将其发送到两个队列

为了更进一步,将SNS添加到这里的混合中,让注册服务向“注册新”主题(而不是队列)发出SNS消息,然后以“扇出”模式向该主题订阅我上面提到的两个队列


这两个队列都将接收消息,但您只需将其加载到SNS一次-如果接下来第三个不相关的服务还需要处理“注册新”事件,您可以创建另一个队列,并将其订阅到主题中—它可以在不依赖于其他服务或不知道其他服务正在做什么的情况下运行—这就是目标。

他们甚至有一个关于如何使用组合SNS+SQS创建扇出场景的教程

太糟糕了,它不支持FIFO队列,所以您必须小心处理无序消息


如果他们有一个一致的哈希解决方案,在尊重消息顺序的同时拥有多个相互竞争的消费者,那就太好了。

一个队列的多个消费者的主要用例是

允许多个使用者使用的机制是,它为使用者提供了处理和删除消息的时间,而不会被另一个使用者同时使用

要解决标准队列的属性, 消费性服务应该是。
如果这是不可能的,一个可能的解决方案是使用,但这种模式有一个有限的消息传递率,是。

这是完美的。我不知道你能用SNS做到这一点!非常感谢。那么FIFO QUE呢?你能用SNS实现严格的排序吗。目前,上述使用SNS和SQS的扇出模式仅支持SQS标准队列。到目前为止,不支持SQS FIFO队列。我还没有发现AWS将来是否打算支持这一点。*FIFO队列现在与SNS*幂等元(sp)兼容