Какова роль MaxAutoRenewDuration в azure служебной шине? - PullRequest
1 голос
/ 24 февраля 2020

Я использую Microsoft.Azure.ServiceBus. ( do c)

Я получил исключение:

Предоставленная блокировка недействительна. Либо истек срок блокировки, либо сообщение уже удалено из очереди.

С помощью следующих вопросов:

1 , 2 , 3 ,

Я могу избежать Exception, установив AutoComplete в false и увеличив продолжительность блокировки очереди Azure до его максимум (от 30 секунд до 5 минут).

_queueClient.RegisterMessageHandler(ProcessMessagesAsync, new 
                         MessageHandlerOptions(ExceptionReceivedHandler)
                         {
                             MaxConcurrentCalls = 1,
                             MaxAutoRenewDuration = TimeSpan.FromSeconds(10),
                             AutoComplete = false
                         }
);

private async Task ProcessMessagesAsync(Message message, CancellationToken token)
{
    await ProccesMessage(message);
}

private async Task ProccesMessage(Message message)
{
    //The complete should be closed before long-timed process
    await _queueClient.CompleteAsync(message.SystemProperties.LockToken);
    await DoFoo(message.Body); //some long running process
}

Мои вопросы:

    1. Этот ответ предполагает, что возникла исключительная ситуация, поскольку срок действия блокировки истек до длительного процесса, но в моем случае я помечал сообщение как завершенное немедленно (до процесса длительного выполнения), поэтому я не уверен, почему изменил продолжительность блокировки с azure сделал разницу? когда я изменяю его на 30 секунд, я снова вижу исключение.
  • Не уверен, относится ли это к вопросу, но какова цель MaxAutoRenewDuration, официальные документы - The maximum duration during which locks are automatically renewed.. Если в моем случае у меня только один получатель приложения, который находится в очереди из этой очереди, то не нужен ли он мне, потому что мне не нужно блокировать сообщение из другого приложения для его захвата? и почему это значение должно быть больше самой длительной длительности блокировки сообщения?

1 Ответ

1 голос
/ 24 февраля 2020

Есть несколько вещей, которые необходимо учитывать.

  1. Продолжительность блокировки
  2. Общее время с момента получения сообщения от брокера

Блокировка длительность проста - на какой срок один конкурирующий потребитель может арендовать сообщение без передачи этого сообщения любому другому конкурирующему потребителю.

Общее время немного сложнее. Ваш обратный вызов ProcessMessagesAsync, зарегистрированный для получения сообщения, - не единственное, что в этом участвует. В предоставленном вами примере кода вы устанавливаете параллелизм равным 1. Если настроена предварительная выборка (очередь получает более одного сообщения с каждым запросом на сообщение или несколько), часы длительности блокировки на сервере начинают тикать для все эти сообщения . Таким образом, если ваша обработка выполняется немного по MaxLockDuration, но для того же примера, последнее предварительно выбранное сообщение ожидало обработки слишком долго, даже если оно выполнено в течение времени, меньшего, чем время блокировки, оно может потерять свою блокировку, и исключение будет быть брошенным при попытке завершить это сообщение.

Вот где MaxAutoRenewDuration входит в игру. То, что он делает, расширяет аренду сообщения с брокером, «повторно блокируя» его для конкурирующего потребителя, который в настоящее время обрабатывает сообщение. MaxAutoRenewDuration должно быть установлено на «возможно максимальное время обработки, которое потребуется для аренды». В вашем примере он установлен на TimeSpan.FromSeconds(10), что крайне мало. Он должен быть установлен как минимум дольше, чем MaxLockDuration, и настроен на самый длинный период времени, который потребуется для работы ProccesMessage. Принимая во внимание предварительную выборку.

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

  1. Включить параллельную обработку, установив MaxConcurrentCalls> 1
  2. Увеличить MaxLockDuration
  3. Уменьшить предварительную выборку сообщений (если вы ее используете)
  4. Сконфигурируйте MaxAutoRenewDuration, чтобы обновить блокировку и преодолеть ограничение MaxLockDuration

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...