3

我有一个简单的视频编码工作者角色,它从队列中提取消息对视频进行编码,然后将视频上传到存储。一切似乎都正常,但偶尔在我完成编码和上传后删除消息时,我会收到“StorageClientException:指定的消息不存在”。尽管视频已处理,但我相信该消息会重新出现在队列中,因为它没有被正确删除。我将消息 visablilty 设置为 5 分钟,没有一个视频的处理时间超过 2 分钟。

  • Worker 角色的另一个实例是否可能正在处理和删除消息?
  • GetMessage() 不会阻止其他工作角色接收相同的消息吗?
  • 我在队列设置中做错了吗?
  • 什么可能导致删除时找不到此消息?

一些代码...

  //onStart() queue setup
  var queueStorage = _storageAccount.CreateCloudQueueClient();
  _queue = queueStorage.GetQueueReference(QueueReference);
  queueStorage.RetryPolicy = RetryPolicies.Retry(5, new TimeSpan(0, 5, 0));
  _queue.CreateIfNotExist();


 public override void Run()
  {
        while (true)
        {
            try
            {
                var msg = _queue.GetMessage(new TimeSpan(0, 5, 0));
                if (msg != null)
                {
                   EncodeIt(msg);
                   PostIt(msg);
                   _queue.DeleteMessage(msg);
                }
                else
                {
                    Thread.Sleep(WaitTime);
                }
            }
            catch (StorageClientException exception)
            {
                BlobTrace.Write(exception.ToString());
                Thread.Sleep(WaitTime);
            }
        }
    }
4

3 回答 3

3

如果编码过程花费的时间超过消息不可见超时(在您的情况下为 5 分钟),则消息将再次出现在队列中。这将导致第二个工作人员开始处理它。但是,很可能当第二个工作人员完成处理时,第一个工作人员已经完成了工作,并正确删除了它。这将导致第二个工作人员在删除阶段失败,因为他的消息不再存在。

这是由于Windows Azure Queues 的轻量级事务模型造成的。它保证消息将至少被处理一次(即使工作人员静默失败),但不保证“只处理一次”

由于您的编码过程似乎是幂等且轻量级的(因为错误很少出现),我只是建议增加不可见超时并在 DeleteMessages 周围显式捕获此异常(通过状态代码)(可选地记录进程持续时间以便能够进一步调整隐形超时)。

于 2010-04-27T06:23:21.920 回答
1

是否有可能比您设置的超时时间更长的五分钟?

于 2010-04-27T06:00:48.437 回答
0

我的开发、生产和舞台都从同一个队列中拉出来,这导致了一些奇怪的行为。我相信这是罪魁祸首。

于 2010-04-30T21:13:11.153 回答