Шаблон повтора

Azure

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

Контекст и проблема

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

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

Решение

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

Схема вызова операции в размещенной службе с помощью шаблона повторных попыток

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

Примечание.

Из-за распространенной природы временных сбоев встроенные механизмы повторных попыток теперь доступны во многих клиентских библиотеках и облачных службах с некоторой степенью настраиваемости для количества максимальных повторных попыток, задержки между повторными попытками и другими параметрами. Встроенная поддержка повторных попыток для многих служб Azure можно найти здесь, а платформа Microsof Entity Framework предоставляет средства для повторных операций базы данных сбоем.

Стратегия повторов

Если приложение обнаруживает сбой при попытке отправить запрос к удаленной службе, оно может обработать этот сбой с помощью стратегий ниже:

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

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

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

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

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

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

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

Проблемы и рекомендации

При выборе схемы реализации этого шаблона следует учитывать следующие моменты.

Влияние на производительность

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

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

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

Идемпотентность

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

Тип исключения

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

Согласованность транзакций

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

Общее руководство

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

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

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

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

Когда следует использовать этот шаблон

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

Этот шаблон может оказаться неэффективным в следующих случаях:

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

Проектирование рабочей нагрузки

Архитектор должен оценить, как шаблон повторных попыток можно использовать в проектировании рабочей нагрузки для решения целей и принципов, описанных в основных принципах Платформы Azure Well-Architected Framework. Например:

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

- RE:07 Самосохранение
- Временные ошибки RE:07

Как и любое решение по проектированию, рассмотрите любые компромиссы по целям других столпов, которые могут быть представлены с этим шаблоном.

Пример

Сведения о реализации политики повторных попыток с помощью руководства по .NET см. в подробном примере с помощью пакета SDK Azure с встроенной поддержкой механизма повторных попыток.

Следующие шаги

  • Прежде чем писать пользовательскую логику повторных попыток, рассмотрите возможность использования общей платформы, например Polly для .NET или устойчивости4j для Java.

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

  • Шаблон надежного веб-приложения показывает, как применить шаблон повторных попыток к веб-приложениям, конвергентным в облаке.

  • Для большинства служб Azure клиентские пакеты SDK включают встроенную логику повторных попыток. Подробнее см. в разделе Повторная попытка в службах Azure.

  • Шаблон прерывателя. Если предполагается длительный сбой, лучше реализовать шаблон автоматического выключения. Объединение шаблонов повторных попыток и автоматического останова обеспечивает комплексный подход к обработке сбоев.