如何保证Amazon SQS只收到一次消息?

问题描述 投票:4回答:2

我正在使用Amazon SQS队列向外部系统发送通知。

如果在使用SQS'SendMessage时HTTP请求失败,我不知道消息是否已排队。我的默认策略是重试将消息发布到队列,但是有两次发布消息的风险,这可能是不可接受的,具体取决于用例。

如果消息正文中存在重复(或某种消息元数据,例如我们可以提供的唯一ID),是否有办法让SQS拒绝消息,以便我们可以重试,直到消息被接受为止,并且有信心如果第一个请求已经排队,那么不会有重复,但是响应已经丢失了?

amazon-sqs
2个回答
6
投票

不,SQS中没有这样的机制。更进一步,消息也可能被传递两次或更多次(至少一次传递语义)。因此,即使存在这样的机制,您也无法保证消息不会多次传递。

见:http://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/DistributedQueues.html

对于一次性交付,您需要在发送端和接收端进行某种形式的事务(并且HTTP不是事务性协议)。


3
投票

AFAIK,现在SQS确实支持所要求的!

请参阅标题为Amazon SQS Introduces FIFO Queues with Exactly-Once Processing and Lower Prices for Standard Queues的“新内容”帖子

SQS FAQ说:

FIFO队列提供一次性处理,这意味着每个消息一次传递并保持可用,直到消费者处理它并删除它。重复项不会引入队列。

还有一个AWS Blog post对这个问题有更多的了解:

这些队列旨在保证消息按照发送顺序正确处理一次,并且没有重复。

......

完全一次处理适用于单用户和多用户方案。如果在多用户环境中使用FIFO队列,则可以将队列配置为仅在删除当前消息或可见性超时到期后才向其他使用者显示消息。在这种情况下,最多一个消费者将主动处理消息;其他消费者将等到第一个消费者完成或失败。

当SQS之外的网络问题阻止邮件发件人了解操作的状态并导致发件人重试该呼叫时,有时会发生重复的邮件。 FIFO队列使用多种策略来检测和消除重复的消息。除了基于内容的重复数据删除之外,还可以在为FIFO队列调用SendMessage时包含MessageDeduplicationId。 ID最长可达128个字符,如果存在,则优先级高于基于内容的重复数据删除。

© www.soinside.com 2019 - 2024. All rights reserved.