Очередь хранилища Azure - много времени на обработку

Мне нужно создать довольно много отчетов, и на создание отчета может уйти около 5 минут, большой объем данных, много разных источников.

Клиент отправляет сообщения в очередь хранилища Azure. Есть рабочие роли, которые обрабатывают сообщения и создают отчеты.

Если я хочу масштабировать это, скажем, у меня есть 10 рабочих ролей, которые будут обрабатывать сообщения из очереди и генерировать отчеты. Затем я буду добавлять сообщения в очередь следующим образом:

  • сообщение 1: обработать отчеты с 1 по 5
  • сообщение 2: отчеты о процессе с 6 по 11 ........
  • сообщение 10: обрабатывайте отчеты от 50 до 55 (диапазон может быть неточным)

Если моя рабочая роль 1 примет первое сообщение и заблокирует его, но процесс займет 5 минут, срок действия блокировки истечет, и сообщение снова станет видимым в очереди, поэтому рабочая роль 2 примет его и начнет его обрабатывать. ... и так далее

Как я могу избежать того, что сообщение очереди будет использовано только один раз, имея в виду, что задача долгая?


person David Dury    schedule 05.03.2015    source источник


Ответы (1)


Прежде всего: используя очереди хранилища Azure, вы должны быть готовы к тому, что все ваши операции будут идемпотентными: если ваш элемент очереди обрабатывается несколько раз, каждый раз должен получаться один и тот же результат. Причина, по которой я поднимаю это: просто нет способа гарантировать, что вы обработаете сообщение один раз (если вы не проверите свойство DequeueCount сообщения и не остановите обработку соответствующим образом) из-за неожиданных событий, таких как сбой / перезагрузка вашего экземпляра роли или ваш код обработки элемента очереди делает что-то неожиданное, например генерирует исключение.

Далее: Тайм-аут невидимости сообщений в очереди может быть увеличен программно. Это можно сделать через api очереди или через один из языковых SDK. В С # (что-то вроде этого - я это не тестировал), продлевая дополнительную минуту:

queueMessage.UpdateMessage(message, 
    TimeSpan.FromSeconds(60),
    MessageUpdateFields.Visibility);

Вы также можете изменить сообщение в процессе (возможно, в качестве подсказки к вашему коду, чтобы вы знали, какой из 5 отчетов был завершен. Это должно помочь вашей конкретной проблеме: в случае повторной обработки сообщения вы этого не сделаете). необходимо обработать все пять отчетов, если сообщение было изменено и теперь содержит что-то вроде "process reports from 3-5"). Примечание. Вы можете комбинировать флаги MessageUpdateFields с помощью |:

queueMessage.UpdateMessage(message, 
    TimeSpan.FromSeconds(0),
    MessageUpdateFields.Content);

И наконец: если вас беспокоит время, необходимое для обработки пакета отчетов, возможно, переосмыслите, почему вы обрабатываете пять отчетов в каждом сообщении, а не один отчет на сообщение. Вы всегда можете читать сообщения очереди в пакетном режиме. Это становится немного субъективным, поскольку на самом деле нет правильного или неправильного способа сделать это, но вам просто нужно подумать об этом.

person David Makogon    schedule 05.03.2015