Рабочий процесс Windows: почему они застряли в постоянстве?

StackOverflow https://stackoverflow.com/questions/1201867

  •  05-07-2019
  •  | 
  •  

Вопрос

У меня есть экземпляр рабочего процесса Windows, который использует постоянство SQL и размещается в среде выполнения веб-сайта, поскольку рабочие процессы запускаются при отправке форм ASP.NET. Большую часть времени он работает отлично, но я заметил случаи, когда мне приходилось пинать вещи:

Я заметил, что nextTimer давно просрочен, даже на несколько часов. Иногда поля ownerID и ownUntil в базе данных постоянства имеют значение null, иногда нет. & Quot; разблокировано " и "заблокирован" оба поля всегда "1".

... и тогда среда выполнения рабочего процесса не подберет его обратно, пока я не исключу " владельца " поля, если они заполнены и запускают пул приложений с повторным использованием, и в большинстве случаев после этого дела идут хорошо. Там нет ошибок (у меня есть блоки try / catch вокруг всего и записываю все, что попало в файл трассировки), так что это не так.

Все операции задержки, вызывающие постоянство, установлены на одну минуту, а продолжительность владения для среды выполнения также составляет 60 секунд. Код, на котором он застревает, всегда должен занимать меньше минуты.

Когда я пишу это, мне любопытно, не вызывают ли это повторные циклы пула приложений / домена приложения ... когда рабочий процесс пытается вызвать какой-либо метод во время выполнения, он занят раскручиванием домена / пула приложения и может утечка в течение 60 секунд продолжительности владения. Это звучит правдоподобно, и не приведет ли это к неправильной регидратации?

За исключением того, что может вызвать такое поведение, которое я вижу? Я не хочу присматривать за рабочим временем каждый день, отрывая застрявшие рабочие процессы.

Это было полезно?

Решение

Вполне вероятно, что переработка домена приложения является большой частью вашей проблемы. IIS перезапустит AppDomain, как только последний запрос будет завершен. Однако он не видит код, выполняющийся в другом потоке, как часть этого запроса. Это одна из основных причин использования ManualWorkflowSchedulerService при размещении в IIS. Но когда вы используете опцию активных таймеров, она все еще использует фоновый поток для выполнения действий рабочего процесса.

Также убедитесь, что вы выгружаете рабочие процессы, как только они простаивают. Самый простой способ сделать это - использовать параметр UnloadOnIdle в SqlWorkflowPersistenceService.

PersistenceService проверяет рабочие процессы с истекшим сроком владения, но только во время запуска. Поэтому, скорее всего, перезапуск рабочего процесса IIS также перезапустит старые рабочие процессы без какой-либо дополнительной работы. Но так как это дело новых проблем ..... Просто очистка старого владельца также должна помочь. В этом случае служба PersistenceService должна просто перезагрузить рабочие процессы в следующий раз. Единственная хитрость заключается в том, чтобы узнать, какой идентификатор runitme является старым, а какой нет (свойство, содержащее значение, не является общедоступным).

Еще одна вещь, которую нужно убедиться, - это то, что рабочий процесс IIS перезагружается. Если этого не сделать, среда выполнения WF отсутствует, поэтому он не может проверить таймеры с истекшим сроком действия. Звучит так, будто у вас есть все, но на всякий случай.

Другие советы

Экземпляры рабочего процесса привязаны к среде выполнения (поэтому несколько сред выполнения могут работать с одной базой данных без обработки обоими экземплярами). Когда AppDomain перезагружается, среда выполнения должна быть остановлена, в результате чего экземпляры становятся разблокированными

Это может быть избыточно, я не проверял это, но это помогло разблокировать экземпляры рабочего процесса:

AppDomain.CurrentDomain.DomainUnload += ((sender, args) =>
                                             {
                                                 if (_runtime.IsStarted)
                                                     _runtime.StopRuntime();
                                             });
AppDomain.CurrentDomain.ProcessExit += ((sender, args) =>
                                            {
                                                if (_runtime.IsStarted)
                                                    _runtime.StopRuntime();
                                            });

Вы проверили часы на своих БД и веб-серверах (если они не на одном сервере)? У меня раньше были подобные проблемы с рабочим процессом, и основная причина заключалась в том, что часы БД и веб-сервера не были синхронизированы.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top