Поделиться через


Действие в случае исключения «Экземпляр заблокирован»

Свойство InstanceLockedExceptionAction хранилища экземпляров рабочего процесса SQL позволяет указать, какое действие должен выполнить поставщик сохраняемости SQL при получении InstanceLockedException. Поставщик сохраняемости получает это исключение, когда пытается заблокировать экземпляр службы рабочего процесса, который в настоящий момент заблокирован другим узлом службы. Возможные значения этого свойства: NoRetry, BasicRetry и AggressiveRetry. Значение по умолчанию — NoRetry. В следующем списке приводится описание этих трех параметров.

  • NoRetry. Узел службы не пытается заблокировать экземпляр службы рабочего процесса и передает InstanceLockedException объект вызывающей. Если рабочий процесс остается в памяти в течение периода, превышающего 60 секунд, используйте NoRetry в качестве повтора. Значение по умолчанию — NoRetry.

  • BasicRetry. Узел службы повторно пытается заблокировать экземпляр службы Workflow Service с линейными интервалами между попытками повтора и передает исключение InstanceLockedException вызывающему объекту в конце последовательности. Если рабочий процесс остается в памяти в течение приблизительно 5–60 секунд, а сообщения поступают пакетами, когда более вероятна отправка всех сообщений на обработку в один и тот же экземпляр на одном и том же узле до выгрузки рабочего процесса, используйте BasicRetry для достижения оптимальной задержки без ненужной затраты ресурсов.

  • AggressiveRetry. Узел службы повторно пытается заблокировать экземпляр службы Workflow Service с экспоненциально растущим интервалом между попытками повтора и передает исключение вызывающему объекту в конце последовательности. Если рабочий процесс остается в памяти в течение очень короткого промежутка времени (менее 5 секунд) либо веб-ферма велика и вероятность доставки другого сообщения на тот же узел невелика, используйте AggressiveRetry для достижения оптимальной задержки.

Функция «Действие при возникновении исключения заблокированного экземпляра» поддерживает следующие сценарии. Во всех сценариях, если свойство instanceLockedExceptionAction хранилища SqlWorkflowInstanceStore имеет значение BasicRetry или AggressiveRetry, узел прозрачно выполняет периодические попытки заблокировать экземпляры.

  1. Включение правильного завершения работы и перезапуск с перекрытием доменов приложений. Предположим, что домен приложения с узлом службы, на котором выполняются экземпляры службы рабочих процессов, перезапускается, а новый домен приложения запускается для параллельной обработки новых запросов, в то время как старый appDomain корректно отключается. Завершение работы ожидает, пока все экземпляры служб рабочих процессов не войдут в неактивном состоянии, после чего сохраняет и выгружает экземпляры. Любые попытки узлами в новом домене приложения заблокировать экземпляр вызовут InstanceLockedException.

  2. Горизонтальное масштабирование устойчивых рабочих процессов в гомогенной ферме серверов. Предположим, что узел фермы серверов, на котором запущен экземпляр рабочего процесса, прекращает работу в результате сбоя и узел рабочего процесса не может снять блокировку запущенного экземпляра. Когда узел служб, запущенный на другом узле фермы, получает сообщение для этого экземпляра рабочего процесса, он пытается заблокировать экземпляры и получает исключение InstanceLockedException. Срок блокировки истечет через некоторое время, поскольку узел, который должен был обновить блокировку, уже не существует.

    Горизонтальное масштабирование устойчивых рабочих процессов в гомогенной ферме серверов. Предположим, что необходимо горизонтально масштабировать устойчивый рабочий процесс с использованием нескольких узлов и балансировки нагрузки на сеть (NLB). Узел рабочих процессов, работающий на одном узле фермы, загружает экземпляр рабочего процесса и обрабатывает сообщение, при этом следующее сообщение экземпляру перенаправляется узлу, который запущен на другом узле, поскольку система NLB не имеет алгоритма перенаправления сообщений на узел, на котором уже запущен экземпляр. При получении сообщения второй узел пытается загрузить экземпляр рабочего процесса и получает исключение InstanceLockedException, поскольку первый узел уже заблокировал экземпляр. Первый узел снимает блокировку с экземпляра после завершения обработки первого сообщения, а второй узел получает блокировку во время второй попытки, загружает этот экземпляр и обрабатывает второе сообщение.