Плановое обслуживание Azure App Service: перезапуски и время простоя

Azure App Service — это платформа как услуга (PaaS) для размещения веб-приложений, REST API и мобильных серверных серверов. Одним из преимуществ предложения является то, что плановое обслуживание выполняется за кулисами. Наши клиенты могут сосредоточиться на развертывании, запуске и обслуживании кода приложения вместо того, чтобы беспокоиться о действиях обслуживания для базовой инфраструктуры. Azure App Service обслуживание — это надежный процесс, предназначенный для предотвращения или минимизации простоя размещенных приложений. Этот процесс остается в значительной степени невидимым для пользователей размещенных приложений. Тем не менее, наши клиенты часто любопытны, если простой, который они испытывают, является результатом нашего планового обслуживания, особенно если они, кажется, совпадают во времени.

Общие сведения

Наш механизм планового обслуживания вращается вокруг архитектуры единиц масштабирования, на которых размещаются серверы, на которых выполняются развернутые приложения. Любой единица масштабирования содержит несколько различных типов ролей, которые работают вместе. Две роли, наиболее важные для нашего механизма планового обновления обслуживания, — это роли Рабочего и Файлового сервера. Более подробное описание всех различных ролей и других сведений об архитектуре App Service см. в Inside the Azure App Service Architecture.

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

Сведения об обновлении экземпляра

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

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

При обновлении рабочей роли механизм обновления аналогично заменяет её новой рабочей ролью. Рабочий элемент переключается следующим образом:

  1. Обновлённый воркер добавляется в ASP.
  2. Приложение запускается на новом рабочем узле.
  3. Наша инфраструктура ожидает запуска приложения.
  4. Новые запросы отправляются в новую рабочую инстанцию.
  5. Разрешено выполнять запросы на старом экземпляре.
  6. Старый рабочий экземпляр удаляется из ASP.

Эта последовательность обычно происходит один раз для каждого экземпляра рабочего процесса в ASP и может занимать несколько минут или часов в зависимости от размера плана и единицы масштабирования.

Основными различиями между этими двумя сценариями являются:

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

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

Непредвиденная обработка сбоев

Хотя в этой статье основное внимание уделяется запланированным действиям по обслуживанию, стоит отметить, что подобное поведение может произойти в результате восстановления платформы после непредвиденных сбоев. Если происходит непредвиденный сбой оборудования, который влияет на роль работника, платформа аналогично заменяет её новой ролью работника. Приложение запускается в этой новой рабочей роли. Если сбой или задержка влияют на роль файлового сервера, связанную с приложением, новая роль файлового сервера заменяет ее. Перезапуск рабочего процесса происходит для всех рабочих ролей. Этот факт важно учитывать при оценке стратегий повышения времени работы приложений.

Стратегии увеличения времени безотказной работы

Большинство размещенных приложений испытывают ограниченное время простоя во время планового обслуживания. Однако этот факт не полезен, если определенные приложения имеют более сложное поведение запуска и поэтому подвержены простою при перезапуске. Если приложения сталкиваются с простоем при каждом перезапуске, устранение простоя становится еще более актуальной. Существует несколько функций, доступных в нашем предложении продуктов Служба приложений, которые предназначены для дальнейшего минимизации простоя в этих сценариях. Широко говоря, существует две категории стратегий, которые можно использовать:

  • Улучшение согласованности запуска приложения
  • Минимизация перезапуска приложения

Улучшение скорости запуска приложения и обеспечение его постоянного успешного выполнения статистически увеличивает уровень успешности. Сначала рекомендуется просматривать параметры, доступные в этой области. Некоторые из них довольно легко реализовать и могут дать большие улучшения. При запуске стратегий согласованности используются функции и методы службы приложений, связанные с кодом приложения или конфигурацией. Минимизация перезапусков — это группа параметров, которые можно использовать, если мы не можем улучшить запуск приложения, чтобы быть достаточно согласованным. Эти параметры, как правило, являются более дорогими и менее надежными, так как они защищают от определённого набора перезапусков. Не удается избежать всех перезапусков. Использование обоих типов стратегий — это то, что очень эффективно.

Стратегии согласованности запуска

Инициализация приложения (AppInit)

Когда приложение начинается с рабочей роли Windows, инфраструктура Azure App Service пытается определить, когда приложение готово к выполнению запросов, прежде чем внешние запросы перенаправляются в эту рабочую роль. По умолчанию успешный запрос к корневому (/) приложению является сигналом о том, что приложение готово к выполнению запросов. Для некоторых приложений это поведение по умолчанию недостаточно, чтобы убедиться, что приложение полностью разогревается. Как правило, это происходит, если корневой каталог приложения имеет ограниченные зависимости, но другие пути используют больше библиотек или внешних зависимостей для работы. Модуль инициализации приложений Internet Information Services (IIS хорошо настраивает поведение прогревания. На высоком уровне он позволяет владельцу приложения определить, какой путь или путь служат индикаторами того, что приложение фактически готово к выполнению запросов. Подробные сведения о реализации этого механизма см. в следующей статье: служба приложений Warm-Up Demystified. При правильной реализации эта функция может привести к нулевому простою, даже если запуск приложения более сложный.

Приложения Linux могут использовать аналогичный механизм с помощью WEBSITE_WARMUP_PATH параметра приложения.

Проверка работоспособности

Проверка работоспособности — это функция, предназначенная для обработки непредвиденных сбоев кода и платформы во время нормального выполнения приложения, но также может быть полезной для повышения устойчивости запуска. Проверка работоспособности выполняет две различные функции восстановления — удаление сбойного экземпляра из балансировщика нагрузки и замена всего экземпляра на новый. Для обработки периодических сбоев запуска можно использовать удаление экземпляра из системы балансировки нагрузки. Если экземпляр возвращает сбои после запуска, несмотря на использование всех других стратегий, проверка работоспособности может удалить этот экземпляр из подсистемы балансировки нагрузки, пока этот экземпляр не начнет возвращать код состояния 200 для запросов проверки работоспособности снова. Поэтому эта функция действует как защита от сбоев для минимизации времени простоя после запуска. Эта функция может быть полезной, если сбои после запуска являются временными и не требуют перезапуска процесса.

Автоматическое исправление

Auto-Heal for Windows и Linux — это еще одна функция, предназначенная для нормального выполнения приложения, но также может использоваться для улучшения поведения запуска. Если мы знаем, что приложение иногда переходит в неустранимое состояние после запуска, проверка работоспособности не подходит. Однако автоматическое исцеление может автоматически перезапустить рабочий процесс, который может оказаться полезным в этом сценарии. Мы можем настроить правило автоматического восстановления, которое отслеживает неудачные запросы и активирует перезапуск процесса в одном экземпляре.

Тестирование запуска приложения

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

Мы рекомендуем протестировать несколько сценариев

  • Общее тестирование запуска (один экземпляр за раз) для установления частоты успешного запуска отдельного экземпляра. Этот самый простой сценарий должен приблизиться к 100 процентам, прежде чем переходить к другим более сложным сценариям.
  • Смоделировать сбой зависимости запуска. Если приложение имеет какую-либо зависимость от других Azure или служб, отличных от Azure, имитируйте время простоя в этих зависимостях, чтобы выявить поведение приложения в этих условиях.
  • Одновременный запуск многих экземпляров — предпочтительно больше экземпляров, чем в рабочей среде. Тестирование с большим количеством экземпляров часто показывает сбои зависимостей, которые часто используются только во время запуска, например ссылки на KeyVault, конфигурацию приложений, базы данных и т. д. Эти зависимости должны проверяться для объема запросов, создаваемых одновременным перезапуском экземпляра.
  • Добавление экземпляра под полную нагрузку— убедитесь, что AppInit настроен правильно, и приложение можно инициализировать полностью до отправки запросов в новый экземпляр. Горизонтальное масштабирование вручную — это простой способ воспроизведения перемещения экземпляра во время обслуживания.
  • Перезапуск перекрываемого рабочего процесса — снова проверяет, настроен ли AppInit правильно, и если запросы могут успешно завершиться по мере завершения старого рабочего процесса и запуска нового рабочего процесса. Изменение переменной среды под нагрузкой может имитировать изменение файлового сервера.
  • Несколько приложений в одном плане — если в плане содержится несколько приложений, следует одновременно выполнить все тесты для всех приложений.

Ведение журнала запуска

Возможность ретроактивно устранять сбои запуска в рабочей среде — это решение, отдельное от использования тестирования для повышения согласованности запуска. Тем не менее, это равно или более важно, так как, несмотря на все наши усилия, мы не можем имитировать все типы реальных сбоев в тестовой среде или среде качества обслуживания. Это также наиболее слабая область для журналирования, так как инициализация инфраструктуры журналирования является еще одной операцией при старте, которую необходимо выполнить. Порядок операций для инициализации приложения является важным фактором по этой причине и может стать куриным и яичным типом проблемы. Например, если необходимо настроить ведение журнала на основе ссылки KeyVault, и мы не можем получить значение KeyVault, как регистрировать этот сбой? Мы могли бы рассмотреть возможность дублирования журнала запуска с помощью отдельного механизма ведения журнала, который не зависит от других внешних факторов. Например, ведение журнала этих типов сбоев запуска на локальный диск. Когда вы включаете общую функцию ведения журнала, например .NET Core stdout logging, это может быть контрпродуктивно, поскольку ведение журнала продолжает генерировать данные даже после запуска, и со временем это может заполнить диск. Эту функцию можно использовать стратегически для устранения воспроизводимых сбоев запуска.

Стратегии минимизации перезапусков

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

Внимание

Полностью избежать перезапуска невозможно. Следующие стратегии помогут сократить количество перезапусков.

Локальный кэш

Локальный кэш — это функция, предназначенная для повышения устойчивости из-за сбоев внешнего хранилища. На высоком уровне создается копия содержимого приложения на локальном диске экземпляра, на котором он выполняется. Это изолирует приложение от непредвиденных сбоев хранилища, но также предотвращает перезапуск из-за изменений файлового сервера. Использование этой функции может значительно сократить количество перезапусков во время общедоступного обслуживания — обычно она может устранить около двух третьих этих перезапусков. Так как он в основном избегает одновременных перезапусков рабочих процессов, наблюдаемое улучшение согласованности запуска приложения может быть еще больше. Локальный кэш имеет некоторые последствия проектирования и изменения поведения приложения, поэтому важно полностью протестировать приложение, чтобы убедиться, что приложение совместимо с этой функцией.

Уведомления о плановом обслуживании и парные регионы

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

Управление окном планового обслуживания в среде App Service Environment v3

Контроль окна обслуживания доступен только в изолированных App Service Environment v3. Если мы уже используем App Service Environment (ASE) или если это возможно использовать ASE, это позволяет нашим клиентам контролировать поведение планового обслуживания в высокой степени. Невозможно контролировать время планового обслуживания в мультитенантной среде.