27

我知道为了带来巨大的可扩展性和可靠性,SQS 对资源进行了广泛的并行化。它甚至为小型队列使用冗余服务器,甚至发布到队列的消息也作为多个副本冗余存储。这些是阻止它像在 RabbitMQ 中那样只发送一次的因素。我什至看到已删除的消息被传递。

对开发人员的影响是,他们需要为消息的多次传递做好准备。亚马逊声称这不是问题,但它确实是,然后开发人员必须使用一些同步构造,如数据库事务锁或发电机数据库条件写入。这两者都会降低可扩展性。

问题是,

针对重复投递问题,message-invisible-period特性如何成立?不保证该消息是不可见的。如果开发人员必须自己安排同步,那么隐身期有什么好处。我已经看到消息被重新传递,即使它们应该是不可见的。

编辑

在这里我包括一些参考

  1. 使用 Amazon SQS 实现“仅一次交付”行为的最佳实践是什么?
  2. http://aws.amazon.com/sqs/faqs/#How_many_times_will_I_receive_each_message
  3. http://aws.amazon.com/sqs/faqs/#How_does_Amazon_SQS_allow_multiple_readers_to_access_the_same_message_queue_without_losing_messages_or_processing_them_many_times
  4. http://aws.amazon.com/sqs/faqs/#Can_a_deleted_message_be_received_again
4

1 回答 1

17

消息不可见性解决了与保证一次且仅一次传递不同的问题。考虑对队列中的项目进行长时间运行的操作。如果处理器在操作过程中出现故障,您不想删除该消息,而是希望它重新出现并由另一个处理器再次处理。

所以模式是...

  1. 将项目写入(推送)到队列中
  2. 查看(查看)队列中的项目
  3. 将项目标记为不可见
  4. 对项目执行流程
  5. 写结果
  6. 从队列中删除(弹出)项目

因此,无论您是否收到重复交付,您仍然需要确保处理队列中的项目。如果您在将其从队列中拉出时将其删除,然后您的服务器死机,您可能会永远丢失该消息。它通过使用现场实例来实现积极的扩展 - 并保证(使用上述模式)您不会丢失消息。

但是 - 它不保证一次且仅一次交付。但我不认为它是为这个问题而设计的。我也不认为这是一个无法克服的问题。在我们的例子中(我可以明白为什么我以前从未注意到这些问题)——我们正在将结果写入 S3。如果它用相同的数据覆盖相同的文件,这没什么大不了的。当然,如果它是通过银行账户进行的借记交易,您可能需要某种相关 ID……而且大多数系统已经有了这些。所以如果你得到一个重复的相关值,你会抛出一个异常并继续前进。

好问题。为我突出了一些东西。

于 2013-09-02T09:44:11.633 回答