我有一个基于服务的应用程序,它使用具有多个队列和多个消费者的Amazon SQS。我这样做是为了实现基于事件的体系结构并解耦所有服务,其中不同的服务对其他系统的状态变化做出反应。例如:
我遇到了很多问题:
我想我的问题是:我应该使用哪些模式来确保我可以在SQS中为单个队列拥有多个使用者,同时确保消息也可以可靠地传递和删除。谢谢你的帮助。
答案 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队列,因此您必须小心处理乱序消息。
如果他们有一个一致的哈希解决方案,以便在尊重消息顺序的同时拥有多个竞争用户,那将是很好的选择。