У меня есть простое видео, кодирующее роль рабочего, что сообщения получений по запросу от очереди кодируют видео, затем загружает видео на устройство хранения данных. Все, кажется, работает, но иногда при удалении сообщения после того, как я сделан, кодируя и загружая, я получаю "StorageClientException: указанное сообщение не существует". Хотя видео обрабатывается, я полагаю, что сообщение вновь появляется в очереди, потому что это не удаляется правильно. У меня есть сообщение visablilty набор к 5 минутам, ни одно из видео не взяло больше чем 2 для обработки.
некоторый код...
//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);
}
}
}
Моя разработка, производство и этап выполнялись из одной очереди, что вызывало странное поведение. Я считаю, что это виноват.
Если процесс кодирования занимает больше времени, чем таймаут невидимости сообщения (5 минут в вашем случае), то сообщение снова появится в очереди . Это заставит второго воркера начать его обработку. Однако есть вероятность, что к тому времени, когда второй воркер закончит обработку, первый воркер уже завершит работу, удалив ее должным образом. Это приведет к сбою второго воркера на этапе удаления, поскольку сообщение для него больше не существует.
Это происходит из-за облегченной модели транзакций Windows Azure Queues . Это гарантирует, что сообщение будет обработано хотя бы один раз (даже если рабочий отказывает тихо), но не гарантирует «только однократную» обработку .
Поскольку ваш процесс кодирования кажется идемпотентным и легким (поскольку ошибка появляется нечасто), я бы просто посоветовал увеличить тайм-аут невидимости и явно зафиксировать это исключение ( по кодам состояния) вокруг DeleteMessages (необязательно регистрируя продолжительность процесса, чтобы иметь возможность настраивать таймауты невидимости в дальнейшем).
Неужели это может занять больше пяти минут, установленных вами в качестве тайм-аута?
{{ 1}}