我正在使用Amazon SQS队列向外部系统发送通知。
如果在使用SQS'SendMessage
时HTTP请求失败,我不知道该消息是否已排队。我的默认策略是重试将消息发布到队列,但是有两次发布消息的风险,这可能是不可接受的,具体取决于用例。
如果消息正文中存在重复(或某种消息元数据,例如我们可以提供的唯一ID),是否有办法让SQS拒绝消息,以便我们可以重试,直到消息被接受为止,并确信如果第一个请求已经排队,那么不会有重复,但是响应已经丢失了?
答案 0 :(得分:6)
不,SQS中没有这样的机制。更进一步,消息也可能被传递两次或更多次(至少一次传递语义)。因此,即使存在这样的机制,您也无法保证消息不会多次传递。
请参阅:http://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/DistributedQueues.html
对于一次性交付,您需要在发送和接收端进行某种形式的交易(并且HTTP不是交易协议)。
答案 1 :(得分: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个字符,如果存在,则优先级高于基于内容的重复数据删除。