Разработка с учетом самовосстановления
Разрабатывая приложение, предусмотрите возможность его самовосстановления при сбоях
В распределенной системе должны произойти сбои. Может произойти сбой оборудования. В сети могут возникнуть временные сбои. Редко вся служба, центр обработки данных или даже регион Azure возникает сбоем, но даже для них в архитектуре рабочей нагрузки они должны быть разработаны. Устойчивость и восстановление должны быть устранены в начале разработки рабочей нагрузки.
Поэтому проектируйте приложение, которое самовосстановляется при возникновении сбоев. Для этого подход должен быть следующим:
- Определяйте сбои.
- Корректно обрабатывайте сбои.
- Журнал и мониторинг сбоев для предоставления операционной информации.
Реагирование на определенный тип сбоя зависит от требований к доступности приложения. Например, если требуется высокий уровень доступности, можно развернуть в нескольких зонах доступности в регионе. Чтобы избежать сбоев, даже в маловероятном случае всего региона Azure, возникающего сбоем, вы можете автоматически выполнить отработку отказа в дополнительный регион во время регионального сбоя. Однако это приведет к повышению затрат и потенциально снижению производительности, чем развертывание в одном регионе.
Кроме того, нужно учитывать не только глобальные сбои, затрагивающие весь регион, которые к тому же довольно редки. Следует уделять не меньше (или даже больше) внимания обработке локальных и кратковременных сбоев, таких как неполадки сетевого подключения или неудачные подключения к базе данных.
Рекомендации
Используйте отдельные компоненты, которые асинхронно взаимодействуют. В идеале компоненты отделяются с точки зрения времени и пространства. Разделение во времени означает, что компоненты не должны присутствовать одновременно для взаимодействия. Разделение в пространстве означает, что отправитель и получатель не должны работать в одном процессе, но они могут везде, где это более эффективно. Несоединяемые компоненты в идеале используют события для взаимодействия друг с другом. Это помогает свести к минимуму вероятность каскадных сбоев.
Настройте механизм повторных попыток при неудачных операциях. Временные сбои могут возникать из-за мгновенной потери сетевого подключения, удаленного подключения к базе данных или времени ожидания при загрузке службы. Реализуйте в приложении логику повторных попыток, чтобы справиться с временными сбоями. Для многих служб Azure механизм автоматических повторных попыток реализован в клиентском пакете SDK. См. дополнительные сведения об обработке временных сбоев и шаблоне повторных попыток.
Обеспечивайте защиту удаленных служб (автоматическое выключение). Повторные попытки дают хороший результат при временных сбоях, но если ошибка не будет устранена, накопится слишком много вызывающих объектов, пытающихся подключиться к проблемной службе. Это может привести к каскадным сбоям при резервном копировании запросов. Используйте шаблон автоматического выключения, чтобы процесс завершался при первой ошибке без выполнения удаленного вызова в случае высокой вероятности сбоя.
Изолируйте критические ресурсы (распределительный блок). Проблема в одной подсистеме иногда приводит к каскадным сбоям. Это может произойти, если сбой приводит к тому, что некоторые ресурсы, такие как потоки или сокеты, не освобождаются своевременно, что приводит к исчерпанию ресурсов. Чтобы избежать этого, используйте шаблон bulkhead для секционирования системы в изолированные группы, чтобы сбой в одной секции не приводит ко всей системе.
Выравнивайте нагрузку. Приложения могут возникать внезапные всплески трафика, которые могут перегружать службы на серверной части. Чтобы избежать этого, используйте шаблон балансировки нагрузки на основе очередей, чтобы накапливать задания в очереди для асинхронного выполнения. Очередь работает как буфер, который сглаживает высокие пики нагрузки.
Выполняйте отработку отказа. Если один экземпляр становится недоступным, переносите работу на другой экземпляр. Для веб-серверов и других компонентов, которые не отслеживают состояние, достаточно просто поместить несколько экземпляров за подсистемой балансировки нагрузки или диспетчером трафика. Если это служба с сохранением состояния, например база данных, используйте реплики и процессы отработки отказа. В зависимости от хранилища данных и его репликации приложение может иметь дело с конечной согласованности.
Компенсируйте проблемные транзакции. По возможности старайтесь не использовать распределенные транзакции, так как они требуют координации между службами и ресурсами. Составляйте нужные операции из нескольких отдельных транзакций меньшего размера. Если же в середине такой операции происходит сбой, используйте компенсирующие транзакции для отмены уже внесенных в этой операции изменений.
Используйте контрольные точки для длительных транзакций. Контрольные точки обеспечивают устойчивость при сбоях длительной операции. Они позволяют возобновлять операцию (например, на другой виртуальной машине) не с самого начала, а с последней успешной контрольной точки. Рассмотрите возможность реализации механизма, который записывает сведения о состоянии задачи через регулярные интервалы, и сохраните это состояние в устойчивом хранилище, доступ к которому может получить любой экземпляр процесса, выполняющего задачу. Таким образом, если процесс завершен, работу, которую он выполнял, можно возобновить с последней контрольной точки с помощью другого экземпляра. Существуют библиотеки, которые предоставляют эти функции, такие как NServiceBus и MassTransit. Они прозрачно сохраняют состояние, в котором интервалы соответствуют обработке сообщений из очередей в Служебная шина Azure.
Деградировать корректно и оставаться адаптивным во время сбоя. Иногда устранить неполадки не получается, но можно сохранить для пользователей ограниченную функциональность приложения. Рассмотрим приложение, которое отображает каталог книг. Если это приложение не может получить эскиз обложки, просто используйте изображение-заполнитель. Иногда работа приложения может не зависеть от целых подсистем. Например, на сайте электронной коммерции, показывающее рекомендации по продукту, вероятно, менее критически важно, чем заказы на обработку.
Выполняйте регулирование клиентов. Иногда небольшое количество пользователей создает избыточную нагрузку, что снижает доступность приложения для других пользователей. Выполняйте регулирование таких клиентов на определенный период времени. См. дополнительные сведения о шаблоне регулирования.
Блокируйте клиентов, совершающих недопустимые действия. Регулирование клиента не означает, что такой клиент является злоумышленником. Он всего лишь превысил квоту на использование службы. Но если клиент превышает квоту постоянно или совершает другие некорректные действия, его можно заблокировать. Определите отдельный процесс для таких случаев, чтобы клиент мог запросить снятие блокировки.
Используйте шаблон выборов лидера. Если некоторая задача требует координации действий, используйте шаблон выбора лидера для назначения координирующего субъекта. В такой схеме координатор не становится единой точкой отказа. Если происходит сбой координатора, просто выбирается новый. Чтобы не создавать с нуля алгоритм выбора лидера, попробуйте применить готовое решение, например Zookeeper.
Выполняйте тестирование путем внесения ошибок. Очень часто бывает так, что хорошо протестирован только "правильный" процесс, но не функционирование в случае ошибок. В рабочей среде системе может потребоваться много времени, чтобы запустить алгоритм обработки ошибок. Проверьте отказоустойчивость системы путем внесения ошибок, отключая реальные службы или моделируя сбой программным образом.
Применяйте хаотическую разработку. Инженерия хаоса расширяет понятие внедрения сбоя путем случайного внедрения сбоев или ненормальных условий в производственные экземпляры.
Используйте зоны доступности. Многие регионы Azure предоставляют зоны доступности, которые являются изолированными наборами центров обработки данных в пределах региона. Некоторые службы Azure можно развертывать зонально, что гарантирует, что они помещаются в определенную зону и могут снизить задержку при взаимодействии между компонентами в одной рабочей нагрузке. Кроме того, некоторые службы можно развернуть с избыточностью зоны, что означает, что Azure автоматически реплицирует ресурс в зонах для обеспечения высокой доступности. Рассмотрим, какой подход обеспечивает лучший набор компромиссов для вашего решения. Дополнительные сведения о разработке решения для использования зон доступности и регионов см . в рекомендациях по использованию зон доступности и регионов.
Структурированный подход к самовосстановлению приложений см. в статье "Проектирование надежных приложений для Azure".