Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Надежные службы — это одна из моделей программирования, доступных в Azure Service Fabric. При изучении жизненного цикла надежных служб важно понимать основные события жизненного цикла. Точное упорядочение событий зависит от сведений о конфигурации.
Как правило, жизненный цикл Надежных служб включает следующие события:
- Во время запуска:
- Службы создаются.
- Службы имеют возможность создавать и возвращать одного или нескольких слушателей.
- Все возвращенные прослушиватели открываются для связи со службой.
- Метод
runAsync
вызывается у службы, чтобы она могла выполнять длительные или фоновые задачи.
- Во время выключения:
- Маркер отмены, который был передан
runAsync
, отменен, и прослушиватели закрыты. - Сам объект службы деструктируется.
- Маркер отмены, который был передан
Порядок событий в "Reliable Services" может немного измениться в зависимости от того, является ли надежная служба бестранзакционной или транзакционной.
Кроме того, для служб с сохранением состояния необходимо учитывать основной сценарий замены. Во время этого этапа роль первичной реплики передается другой реплике (или возвращается) без остановки службы.
Наконец, необходимо подумать об ошибках или сбоях.
Запуск бесстатусной службы
Жизненный цикл бесподдерживаемой службы довольно прост. Ниже приведен порядок событий:
- Служба создается.
-
StatelessService.createServiceInstanceListeners()
вызывается и открываются все возвращенные прослушиватели.CommunicationListener.openAsync()
вызывается для каждого прослушивателя. - Затем параллельно:
- Вызывается метод
runAsync
службыStatelessService.runAsync()
. - При наличии вызывается собственный
onOpenAsync
метод службы. В частности,StatelessService.onOpenAsync()
вызывается. Это нечасто используемое переопределение, но оно доступно.
- Вызывается метод
Завершение работы службы без отслеживания состояния
При завершении работы службы без отслеживания состояния следует использовать тот же шаблон, но в обратном направлении:
- Все открытые прослушиватели закрыты.
CommunicationListener.closeAsync()
вызывается для каждого прослушивателя. - Токен отмены, переданный в
runAsync()
, был отменен. Проверка свойстваisCancelled
у маркера отмены возвращаетtrue
, и, если вызван, методthrowIfCancellationRequested
этого маркера выбрасывает исключениеCancellationException
. - Когда
runAsync()
завершится, вызывается методStatelessService.onCloseAsync()
службы, если он есть. Снова, это не распространённое переопределение, но его можно использовать для того, чтобы безопасно закрывать ресурсы, останавливать фоновую обработку, завершать сохранение внешнего состояния или закрывать существующие подключения. - После завершения
StatelessService.onCloseAsync()
объект службы уничтожается.
Запуск stateful-сервиса
Службы с состоянием имеют шаблон, аналогичный статическим службам, с несколькими изменениями. Ниже приведен порядок событий для запуска службы с отслеживанием состояния:
- Служба создается.
-
StatefulServiceBase.onOpenAsync()
вызывается. Этот вызов обычно не переопределяется в службе. - вызывается
StatefulServiceBase.createServiceReplicaListeners()
.- Если служба является основной службой, открываются все возвращенные прослушиватели.
CommunicationListener.openAsync()
вызывается для каждого прослушивателя. - Если служба — вторичная, открываются только прослушиватели, помеченные как
listenOnSecondary = true
. Наличие прослушивателей, открытых на вторичных файлах, менее распространено.
- Если служба является основной службой, открываются все возвращенные прослушиватели.
- Затем параллельно:
- Если в настоящее время сервис является основным, вызывается метод сервиса
StatefulServiceBase.runAsync()
. -
StatefulServiceBase.onChangeRoleAsync()
вызывается. Этот вызов обычно не переопределяется в службе.
- Если в настоящее время сервис является основным, вызывается метод сервиса
Примечание.
Для новой вторичной реплики StatefulServiceBase.onChangeRoleAsync()
вызывается дважды. Сначала после шага 2, когда он становится бездействующей вторичной системой, а затем во время шага 4, когда он становится активной вторичной системой. Дополнительные сведения о жизненном цикле реплики и экземпляра см. в статье "Реплика и жизненный цикл экземпляра".
Завершение работы службы с отслеживанием состояния
Как и службы без отслеживания состояния, события жизненного цикла во время завершения работы совпадают с событиями во время запуска, но обратно. При завершении работы службы с отслеживанием состояния происходят следующие события:
- Все открытые прослушиватели закрыты.
CommunicationListener.closeAsync()
вызывается для каждого прослушивателя. - Маркер отмены, который был передан
runAsync()
, отменен. Вызов методаisCancelled()
маркера отмены возвращаетtrue
, и если его вызвать, методthrowIfCancellationRequested()
этого маркера вызывает исключениеOperationCanceledException
. Service Fabric ожидает завершенияrunAsync()
.
Примечание.
runAsync
Ожидание завершения необходимо только в том случае, если эта реплика является первичной репликой.
- После
runAsync()
завершения вызывается метод службыStatefulServiceBase.onCloseAsync()
. Этот вызов является необычным переопределением, но он доступен. - После завершения
StatefulServiceBase.onCloseAsync()
объект службы уничтожается.
Обмен основной службы с отслеживанием состояния
Хотя служба с отслеживанием состояния запущена, прослушиватели связи открываются, а runAsync
метод вызывается только для основных реплик этих служб с отслеживанием состояния. Вторичные реплики строятся, но не получают дальнейших вызовов. Пока выполняется служба с отслеживанием состояния, реплика, являющаяся в данный момент основной, может смениться. События жизненного цикла, которые может видеть реплика с сохранением состояния, зависят от того, понижается или повышается она во время переключения.
Для пониженного первичного
Service Fabric требует от первичной реплики, которая была понижена, прекратить обработку сообщений и остановить любые фоновые процессы. Этот шаг аналогичен завершении работы службы. Одно из различий заключается в том, что сервис не разрушается и не закрывается, потому что он остается вторичным. Происходят следующие события:
- Все открытые прослушиватели закрыты.
CommunicationListener.closeAsync()
вызывается для каждого прослушивателя. - Маркер отмены, который был передан
runAsync()
, отменен. Проверка метода токена отменыisCancelled()
возвращаетtrue
. Если метод маркераthrowIfCancellationRequested()
вызывается, он генерирует исключениеOperationCanceledException
. Service Fabric ожидает завершенияrunAsync()
. - Прослушиватели, помеченные как listenOnSecondary = true, открываются.
- Вызывается служба
StatefulServiceBase.onChangeRoleAsync()
. Этот вызов обычно не переопределяется в службе.
Для продвигаемой вторичной
Аналогичным образом, для Service Fabric важно, чтобы вторичная реплика, получая повышение статуса, начинала прослушивать сообщения по проводам и запускала все фоновые задачи, которые ей необходимо выполнить. Этот процесс аналогичен созданию службы. Разница заключается в том, что сама реплика уже существует. Происходят следующие события:
-
CommunicationListener.closeAsync()
вызывается для всех открытых прослушивателей, отмеченных флагом listenOnSecondary = true - Открываются все прослушиватели связи.
CommunicationListener.openAsync()
вызывается для каждого прослушивателя. - Затем параллельно:
- Вызывается метод службы
StatefulServiceBase.runAsync()
. -
StatefulServiceBase.onChangeRoleAsync()
вызывается. Этот вызов обычно не переопределяется в службе.
- Вызывается метод службы
Примечание.
createServiceReplicaListeners
вызывается только один раз и не вызывается повторно во время процесса повышения или понижения реплики; те же ServiceReplicaListener
экземпляры используются, но создаются новые CommunicationListener
экземпляры (вызывая ServiceReplicaListener.createCommunicationListener
метод) после закрытия предыдущих экземпляров.
Распространенные проблемы при завершении работы службы с отслеживанием состояния и первичном понижении
Service Fabric изменяет первичную компоненту службы с отслеживанием состояния по нескольким причинам. Наиболее распространенными причинами являются перебалансирование кластера и обновление приложений. Во время этих операций важно, чтобы служба уважала cancellationToken
. Это также применяется во время нормального завершения работы службы, например, если служба была удалена.
Службы, не обрабатывающие отмену корректно, могут столкнуться с несколькими проблемами. Эти операции выполняются медленно, так как Service Fabric ожидает, чтобы службы завершили работу корректно. Это может в конечном итоге привести к не устанавливающимся обновлениям, которые завершаются с ошибкой и откатываются. Несоблюдение токена отмены также может привести к несбалансированным кластерам. Кластеры становятся несбалансированные, так как узлы становятся горячими. Тем не менее, службы не могут быть перебалансированы, потому что это занимает слишком много времени, чтобы переместить их в другое место.
Так как службы работают с сохранением состояния, вероятно, службы используют надежные коллекции. В Service Fabric при понижении первичного состояния одна из первых вещей, которая происходит, заключается в том, что доступ на запись к базовому состоянию отзывается. Это приводит к второму набору проблем, которые могут повлиять на жизненный цикл службы. Коллекции возвращают исключения в зависимости от времени и условий, таких как перемещение или завершение работы реплики. Важно правильно обрабатывать эти исключения.
Исключения, создаваемые Service Fabric, являются постоянными (FabricException
) или временными (FabricTransientException
). Постоянные исключения должны быть зарегистрированы и брошены. Временные исключения можно извлечь на основе логики повторных попыток.
Важной частью тестирования и проверки надежных служб является обработка исключений, поступающих от использования ReliableCollections
в сочетании с событиями жизненного цикла службы. Рекомендуется всегда запускать службу под нагрузкой. Перед развертыванием в рабочей среде необходимо также выполнить как тестирование хаоса, так и обновления. Эти основные шаги помогают обеспечить правильность реализации службы и правильность обработки событий жизненного цикла.
Заметки о жизненном цикле службы
- Метод
runAsync()
иcreateServiceInstanceListeners/createServiceReplicaListeners
вызовы являются необязательными. Служба может иметь один, оба или ни один из них. Например, если служба выполняет всю работу, реагируя на вызовы пользователей, то реализацияrunAsync()
ей не требуется. Необходимы только прослушиватели связи и связанный с ними код. Аналогичным образом создание и возврат прослушивателей связи является необязательным. Служба может выполнять только фоновую работу, поэтому нужно использовать толькоrunAsync()
. - Он действителен для успешного завершения
runAsync()
услуги и выхода из неё. Это не считается условием сбоя. Он представляет собой фоновую работу завершения обслуживания. Для надежных служб с состоянием,runAsync()
будет вызван снова, если служба будет понижена из первичной, а затем повышена обратно до первичной. - Если служба завершает работу
runAsync()
, вызывая непредвиденное исключение, это сбой. Объект службы был отключен, и сообщается об ошибке работоспособности. - Хотя нет ограничения времени на возврат из этих методов, вы сразу же утратите способность писать. Таким образом, вы не можете завершить какую-либо реальную работу. Рекомендуется как можно быстрее вернуться после получения запроса на отмену. Если служба не отвечает на эти вызовы API в разумный период времени, Service Fabric может принудительно завершить службу. Обычно это происходит только во время обновления приложения или при удалении службы. Это время ожидания составляет 15 минут по умолчанию.
- Сбои в
onCloseAsync()
пути приводят к вызовуonAbort()
. Последний шанс и возможность для службы завершить очистку и освободить все ресурсы, которые они использовали. Обычно это вызывается при обнаружении постоянной ошибки на узле или когда Service Fabric не может надежно управлять жизненным циклом экземпляра службы из-за внутренних сбоев. -
OnChangeRoleAsync()
вызывается при изменении роли реплики сохраняющего состояния службы, например, на первичную или вторичную. Первичным репликам присваивается статус записи (им разрешено создавать и записывать в Надежные коллекции). Вторичные реплики получают состояние чтения (могут читаться только из существующих надежных коллекций). Большая часть работы в сервисе с сохранением состояния выполняется на первичной реплике. Вторичные реплики могут выполнять проверки в режиме только для чтения, создавать отчеты, выполнять интеллектуальный анализ данных или другие задачи, доступные только для чтения.
Дальнейшие действия
- Общие сведения о надежных службах
- Get started with Reliable Services (Начало работы с Reliable Services)