Azure队列 - 我可以验证邮件只读一次吗?

Gil*_*Gat 11 azure azure-storage azure-storage-queues

我正在使用Azure队列,并从队列中读取几个不同的进程.
我的系统构建方式假定每条消息只读一次.
这篇Microsoft文章声称Azure队列至少有一次传递保证,这可能意味着两个进程可以从队列中读取相同的消息.
StackOverflow线程声称,如果我使用GetMessage,则该消息对于隐身超时的所有其他进程变得不可见.

假设我使用GetMessage()并且在DeleteMessage之前从不超过消息不可见时间,我可以假设我只会获得每条消息一次吗?

Sha*_* Xu 10

我认为队列消息中有一个属性命名DequeueCount,这是该消息已出列的次数.它由队列服务维护.我认为您可以使用此属性来确定您的消息之前是否已被阅读过.

http://msdn.microsoft.com/en-us/library/microsoft.windowsazure.storageclient.cloudqueuemessage.dequeuecount.aspx(存储客户端1.7)

http://msdn.microsoft.com/en-us/library/windowsazure/microsoft.windowsazure.storage.queue.cloudqueuemessage.dequeuecount.aspx(存储客户端2.0)

  • 那个'DequeueCount`在并发场景中是否一致?两个线程可以同时将同一个消息出列,并且都将其视为"DequeueCount:0"吗? (2认同)

San*_*tia 8

不会.以下情况可能发生:

  • GetMessage函数()
  • 在数据库中添加一些记录......
  • 生成一些文件......
  • DeleteMessage() - >意外失败(崩溃的进程,重新启动的实例,网络连接问题,......)

在这种情况下,您的逻辑在不调用DeleteMessage的情况下执行.这意味着,一旦隐身超时到期,消息将出现在队列中并再次处理.您需要确保您的流程是幂等的:

幂等性是数学和计算机科学中某些操作的特性,它们可以多次应用而不会改变初始应用之外的结果.

另一种解决方案是使用具有ReceiveAndDelete模式的服务总线队列(请参阅如何从队列接收消息下的页面).如果您收到该消息,它将被标记为已消耗,并且永远不会再次出现.通过这种方式,您可以确保它是最多一次交付(请参阅此处与存储队列的比较).但话说回来,如果在处理消息时发生了某些事情(即:服务器崩溃,......),您可能会丢失有价值的信息.

更新:

这将模拟存储队列中的At-Most-Once.消息可以通过GetMessage多次到达,但只会由业务逻辑处理一次(存在一些业务逻辑永远不会执行的风险).

  • GetMessage函数()
  • DeleteMessage可以()
  • AddRecordsToDatabase()
  • GenerateFiles()

  • 跟进 Sandrino 的示例:假设我的队列有 itemA 并且我有两个进程。有可能两个进程都会执行 GetMessage() 并获取 ItemA,但其中一个进程(较慢的进程)在调用 DeleteMessage() 时会失败,因此不会执行业务逻辑。它是否正确? (2认同)