Как очередь служебной шины Azure гарантирует доставку не более одного раза?

Согласно этому Служебная шина doc поддерживает два режима получения и удаления и блокировки просмотра.

При использовании режима Peek-Lock, если потребитель вылетает / зависает / выполняет очень долгую сборку мусора сразу после обработки сообщения, но до того, как messageId станет «Completed» и истечет время видимости, есть вероятность, что одно и то же сообщение будет доставлено дважды.

Тогда как Microsoft утверждает, что служебная шина поддерживает режим доставки не более одного раза. Это из-за режима получения и удаления, который отправляет сообщения только один раз, но опять же, если что-то происходит, пока потребители обрабатывают сообщение, эта ценная информация теряется.

Если да, то как лучше всего обеспечить точную однократную доставку с использованием шины служб Azure в качестве очереди и функций Azure в качестве потребителей.

P.S. Единственный подход, о котором я могу думать, - это хранение MessageID в blob, но поскольку в моем случае количество MessageID может быть очень большим, хранение и загрузка всех из них - неправильный подход.


person himanshu219    schedule 22.06.2018    source источник


Ответы (1)


Функции Azure всегда будут использовать сообщения служебной шины в режиме Peek-Lock. Точно однажды доставка в общем случае в принципе невозможна: всегда есть шанс, что приложение-потребитель выйдет из строя в неподходящее время непосредственно перед завершением сообщения, а затем сообщение будет доставлено повторно.

Вы должны стремиться реализовать обработку «Эффективно один раз». Обычно это достигается с помощью идемпотентного процессора сообщений.

Сохранение идентификаторов сообщений (дедупликация на стороне потребителя) - это один из вариантов. У вас может быть политика для очистки старых идентификаторов сообщений, чтобы размер такого хранилища оставался управляемым. Чтобы сделать это на 100% надежным, вам нужно будет сохранить идентификатор сообщения в той же транзакции, что и другие модификации, сделанные процессором.

Другие варианты действительно зависят от вашего сценария обработки. Найдите способ сделать его идемпотентным - чтобы обработка одного и того же сообщения несколько раз была функционально такой же, как и его обработка только один раз.

person Mikhail Shilkov    schedule 22.06.2018
comment
Какие еще варианты. В моем сценарии я использую путь из служебной шины, функция Azure загружает большой двоичный объект, используя путь, массирует данные и отправляет их во внешнюю службу через HTTP. В случае успеха она удаляет сообщение из служебной шины. - person himanshu219; 23.06.2018
comment
В этом случае внешняя служба должна иметь возможность дедуплицировать ваши запросы, например проверив, есть ли уже данные с тем же путем / идентификатором blob - person Mikhail Shilkov; 23.06.2018
comment
У меня нет контроля над внешним сервисом. И, кстати, почему мы не можем применить логику дедупликации в функциях Azure? - person himanshu219; 23.06.2018
comment
Потому что ваш вызов экстренальной службы может потерпеть неудачу, и вы не узнаете, удалось ли это на самом деле - person Mikhail Shilkov; 23.06.2018