Есть несколько вещей, которые необходимо учитывать.
- Продолжительность блокировки
- Общее время с момента получения сообщения от брокера
Блокировка длительность проста - на какой срок один конкурирующий потребитель может арендовать сообщение без передачи этого сообщения любому другому конкурирующему потребителю.
Общее время немного сложнее. Ваш обратный вызов ProcessMessagesAsync
, зарегистрированный для получения сообщения, - не единственное, что в этом участвует. В предоставленном вами примере кода вы устанавливаете параллелизм равным 1. Если настроена предварительная выборка (очередь получает более одного сообщения с каждым запросом на сообщение или несколько), часы длительности блокировки на сервере начинают тикать для все эти сообщения . Таким образом, если ваша обработка выполняется немного по MaxLockDuration
, но для того же примера, последнее предварительно выбранное сообщение ожидало обработки слишком долго, даже если оно выполнено в течение времени, меньшего, чем время блокировки, оно может потерять свою блокировку, и исключение будет быть брошенным при попытке завершить это сообщение.
Вот где MaxAutoRenewDuration
входит в игру. То, что он делает, расширяет аренду сообщения с брокером, «повторно блокируя» его для конкурирующего потребителя, который в настоящее время обрабатывает сообщение. MaxAutoRenewDuration
должно быть установлено на «возможно максимальное время обработки, которое потребуется для аренды». В вашем примере он установлен на TimeSpan.FromSeconds(10)
, что крайне мало. Он должен быть установлен как минимум дольше, чем MaxLockDuration
, и настроен на самый длинный период времени, который потребуется для работы ProccesMessage
. Принимая во внимание предварительную выборку.
Чтобы визуализировать это, представьте, что на стороне клиента имеется очередь в памяти, где сообщения могут храниться, пока вы выполняете последовательную обработку сообщений одно за другим в своем обработчике. , Аренда начинается с момента поступления сообщения от посредника в эту очередь в памяти. Если общее время в очереди в памяти плюс обработка превышает длительность блокировки, аренда теряется. Возможны следующие варианты:
- Включить параллельную обработку, установив
MaxConcurrentCalls
> 1 - Увеличить
MaxLockDuration
- Уменьшить предварительную выборку сообщений (если вы ее используете)
- Сконфигурируйте
MaxAutoRenewDuration
, чтобы обновить блокировку и преодолеть ограничение MaxLockDuration
Примечание о # 4 - это не гарантированная операция. Поэтому существует вероятность того, что вызов брокеру завершится неудачно и блокировка сообщения не будет расширена. Я рекомендую разрабатывать ваши решения для работы в рамках ограничения продолжительности блокировки. В качестве альтернативы, сохраняйте информацию сообщения, чтобы обмен сообщениями не ограничивал вашу обработку.