Предотвращение сбоев службы с помощью проверок работоспособности

О чем мы говорим?

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

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

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

Проверки работоспособности важны, потому что если у вас есть парк из 10 экземпляров серверов за балансировщиком нагрузки, и один из них выходит из строя, но все еще получает трафик, доступность вашей службы упадет в лучшем случае до 90%.

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

К сожалению, все становится сложнее.

Представьте на секунду, что вы усвоили урок и реализовали проверку работоспособности на каждом экземпляре сервера, проверяя возможность подключения к базе данных. Что произойдет, если у вас периодически возникают проблемы с подключением к сети? Вы выводите из строя весь парк экземпляров серверов или ждете, пока проблемы не исчезнут?

Это проблема, связанная с проверками работоспособности - достижение баланса между обнаружением сбоев и реакцией - и это тема, которую мы рассмотрим в этой публикации.

Типы сбоев экземпляра сервера

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

Сбои хоста или локальные сбои вызываются разными причинами: например: неисправностями оборудования, такими как сбой диска; Сбой ОС после апгрейда / обновлений; ограничения безопасности, такие как ограничения на открытие файлов; утечки памяти; и, конечно же, неожиданное поведение приложения.

Сбои в зависимости вызваны внешними факторами. Например: потеря связи с хранилищами данных, такими как внешний уровень распределенного кэширования или база данных; отказы сервисного брокера (очереди); недопустимые учетные данные для объектного хранилища S3; часы не синхронизируются с серверами NTP; проблемы с подключением к сторонним провайдерам (SMS, уведомления и т. д.); и другие неожиданные сетевые проблемы.

Как отмечалось выше, существует множество причин, по которым экземпляр сервера может выйти из строя. Тип проверяемых сбоев определяет тип используемой проверки работоспособности: поверхностная проверка работоспособности на предмет сбоев хоста или локальных сбоев; а также тщательную проверку работоспособности на предмет сбоев зависимостей.

Мелкие и глубокие проверки работоспособности

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

(2) Глубокие проверки работоспособности, с другой стороны, дают вам гораздо лучшее представление о работоспособности вашего приложения, поскольку они могут выявить проблемы с зависимостями. Проблема с глубокими проверками состояния заключается в том, что они дороги - на их выполнение может уйти много времени; нести расходы по зависимостям; и будьте внимательны к ложным срабатываниям - когда проблемы возникают в самих зависимостях.

Действуйте разумно, не открывайте!

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

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

В AWS есть два варианта выполнения балансировки нагрузки между ресурсами с помощью проверок работоспособности: AWS Elastic Load Balancers (ELB) обеспечивает проверки работоспособности ресурсов в регионе AWS; в то время как Route 53 DNS failover обеспечивает проверку работоспособности в регионах AWS. Для клиентов, не использующих AWS ELB, отработка отказа DNS с политиками маршрутизации Weighted Round Robin в Route 53 может обеспечить балансировку нагрузки и возможность переключения при отказе.

Стоит отметить, что ELB - это серверные экземпляры EC2 для проверки работоспособности, тогда как Route 53 может проверять работоспособность любой конечной точки с выходом в Интернет в регионах или за их пределами, поддерживая при этом несколько политик маршрутизации: WRR, конечно, но также маршрутизацию на основе задержки (LBR) и Маршрутизация на основе географического местоположения / близости (GBR) - и все будут соблюдать проверку работоспособности.

Что наиболее важно в нашем случае с отказоустойчивыми архитектурами, балансировщики нагрузки AWS Elastic Load Balancer (как Сеть, так и Приложение) и Восстановление после отказа Route 53 DNS поддерживают открытие при сбое, то есть маршрутизацию запросов ко всем целевым объектам, даже если ни один сервер не сообщает о работоспособности.

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

Наконец, если вы используете Route 53 или AWS ELB, вам следует всегда отдавать предпочтение глубоким проверкам работоспособности перед неглубокими или использовать их комбинацию - так как вместе они могут легче определить место, где происходит сбой.

Взгляните на проверки работоспособности Route 53

Route 53 поддерживает три различных типа проверки работоспособности: (1) мониторинг конечных точек, наиболее распространенный тип; (2) рассчитанные проверки работоспособности, используемые, когда у вас есть комбинация различных проверок работоспособности (например, мелкая и глубокая); и (3) проверки работоспособности, отслеживающие сигналы тревоги CloudWatch.

На Маршруте 53 используются средства проверки работоспособности, расположенные по всему миру. Каждая программа проверки работоспособности отправляет запросы к указанной конечной точке, чтобы определить, исправна ли конечная точка: с интервалом в 30 секунд, называемым «стандартным»; или с интервалом в 10 секунд, что называется «быстро».

Интересный факт: средства проверки работоспособности Route 53 в разных местах не взаимодействуют друг с другом, поэтому ваша система мониторинга может видеть несколько запросов в секунду независимо от выбранного вами интервала. Не волнуйтесь, это нормально - случайность в действии

Средство проверки работоспособности в каждом месте оценивает работоспособность цели на основе двух значений: (1) время отклика (таким образом, важность тайм-аута объяснялась ранее); и (2) порог сбоя, который представляет собой количество последовательных успешных (или неудачных) запросов.

Наконец, служба Route 53 собирает все данные от средств проверки работоспособности в разных местах (по умолчанию 8) и определяет, исправна ли цель.

Если более 18% проверяющих работоспособности сообщают, что конечная точка исправна, Route 53 будет считать ее исправной. Точно так же, если 18% или меньше средств проверки работоспособности сообщают, что конечная точка исправна, Route 53 сочтет цель неработоспособной.

Почему 18%? Это значение было выбрано, чтобы избежать временных ошибок и условий локальной сети. AWS оставляет за собой право изменить это значение в будущем :)

Забавный факт: 18% - это не магия, а потому, что в большинстве случаев есть 16 проверок здоровья, разбросанных по 8 регионам, которые исследуют конкретную цель. Поскольку мы проверяем, достижима ли цель как минимум из 3 зон доступности, чтобы считать ее работоспособной, это дает 3/16 = 18%.

И последнее, но не менее важное: для быстрого переключения DNS на Route 53 необходимо, чтобы записи DNS имели TTL не более 60 секунд. Это минимизирует время, необходимое для того, чтобы трафик перестал перенаправляться к вышедшей из строя конечной точке.

Демонстрация: сбой при открытии маршрута 53 из-за неудачных проверок работоспособности

Чтобы продолжить пример, который я представил в моей серии сообщений в блоге о многорегиональной архитектуре, давайте взглянем на сбой открытия маршрута 53.

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

Я настроил проверки работоспособности DNS Route 53 при отказе, используя API работоспособности, развернутый здесь.

И я сделал то же самое для каждого региона. Вы можете увидеть политику маршрутизации между двумя региональными конечными точками API из шлюза API, а также целевую проверку работоспособности.

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

Однако, как вы можете видеть, запросы все еще направляются к конечным точкам - Route 53 успешно не открывается.

Соображения при внедрении проверок работоспособности:

  • Создайте карту зависимостей критических путей запроса, которые являются обязательными для каждого запроса, и разделите рабочие и нерабочие зависимости. Меньше всего вам нужно, чтобы политики балансировки нагрузки были чувствительны к некритическим службам (например, сбоям из-за служб мониторинга).
  • При проверке нескольких зависимостей в сети, если возможно, вызывайте их одновременно. Это ускорит процесс и предотвратит задержку вашей глубокой проверки работоспособности специалистами по проверке работоспособности.
  • Не забывайте тайм-аут, ухудшайте качество или даже отклоняйте запросы зависимостей, если это необходимо, и не реагируйте чрезмерно, то есть не прерывайте работу при первой временной ошибке. Хорошей практикой является обеспечение верхнего предела времени отклика для каждой из зависимостей, а еще лучше - использовать автоматический выключатель для всех вызовов методов зависимостей. Более подробную информацию можно найти здесь.
  • Когда зависимости не работают, не забудьте проверить все внутренние исключения любой данной ошибки рекурсивным образом, поскольку временные исключения часто скрыты внешними исключениями разных типов.
  • Остерегайтесь времени «запуска» ваших глубоких проверок работоспособности. Вы не хотите, чтобы некритические зависимости мешали вашим недавно запущенным экземплярам сервера обрабатывать трафик. Это особенно важно в ситуациях, когда ваша система пытается восстановиться после сбоев. Одно из решений - зондировать поверхностную проверку работоспособности во время запуска, и когда все зависимости станут зелеными, превратить эту поверхностную проверку работоспособности в глубокую проверку работоспособности.
  • Убедитесь, что на ваших экземплярах сервера есть зарезервированные ресурсы и выделены приоритеты для своевременного ответа на вопросы проверки работоспособности (помните, что у проверок работоспособности тоже есть тайм-ауты). Последнее, что вам нужно в производственной среде, - это уменьшить ваш парк экземпляров серверов, когда у вас есть всплеск трафика, потому что экземпляры ваших серверов не смогли вовремя ответить на проверку работоспособности. Это могло превратиться в разрушительный эффект каскадного отказа из-за перегрузки.
  • При нагрузочном тестировании экземпляров сервера обратите внимание на ваше максимальное количество одновременных подключений для каждого экземпляра и проверьте это число во время проверки работоспособности (не забудьте также учитывать подключения средств проверки работоспособности). Часто это максимальное количество одновременных подключений является ограничивающим фактором для масштабирования.
  • Ой, чуть не забыл - обязательно защитите конечные точки API проверки работоспособности !!!!!! :-)

Подведение итогов

На сегодня все, ребята! Надеюсь, вам понравился этот пост.

Не стесняйтесь оставлять отзывы или делиться своим мнением.

Часть 1 - Масштабирование неудач

Часть 2 - Предотвращение каскадных отказов

Часть 3 - Предотвращение сбоев обслуживания с помощью проверки работоспособности

Часть 4 - Кеширование для повышения отказоустойчивости

-Адриан