Поделиться через


Обработка временных сбоев

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

В этой статье приведены общие рекомендации по обработке временных сбоев.

Почему временные сбои происходят в облачных системах?

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

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

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

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

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

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

Проблемы

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

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

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

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

Общие рекомендации

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

Определение наличия встроенного механизма повторных попыток

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

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

Определение того, подходит ли операция для повторных попыток

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

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

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

Определение соответствующего количества повторных попыток и интервала

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

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

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

    • Экспоненциальная задержка. Приложение ожидает некоторое время до первого повтора, а затем экспоненциально увеличивает время между каждой последующей повторным попыткой. Например, он может повторить операцию через 3 секунды, 12 секунд, 30 секунд и т. д.

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

    • регулярные интервалы. Приложение ожидает одного и того же периода времени между каждой попыткой. Например, она может повторить операцию каждые 3 секунды.

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

    • рандомизация. Любая из стратегий повторных попыток, перечисленных ранее, может включать элемент случайности, чтобы предотвратить одновременную отправку клиентом нескольких повторных запросов. Например, один экземпляр может повторить операцию через 3 секунды, 11 секунд, 28 секунд и т. д., а другой экземпляр может повторить операцию через 4 секунды, 12 секунд, 26 секунд и т. д. Случайное использование — это полезный метод, который можно объединить с другими стратегиями.

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

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

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

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

  • Используйте тип исключения и все содержащиеся в ней данные или коды ошибок и сообщения, возвращаемые службой, для оптимизации количества повторных попыток и интервала между ними. Например, некоторые исключения или коды ошибок (например, HTTP-код 503, служба недоступна, с заголовком Retry-After в ответе) могут указывать, сколько времени может длиться ошибка, или что служба завершилась ошибкой и не будет отвечать на любую последующую попытку.

Избегайте антипаттернов

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

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

  • Никогда не выполняйте немедленную повторную попытку более одного раза.

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

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

Тестирование стратегии повторений и её реализации

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

    • Внедрять временные и постоянные сбои в службу. Например, отправьте недопустимые запросы или добавьте код, который обнаруживает тестовые запросы и отвечает с различными типами ошибок. Примеры использования TestApi см. в разделе Тестирование внедрения ошибок с помощью TestApi и Введение в TestApi — часть 5: API для внедрения ошибок в управляемый код.

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

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

    • Для HTTP-ориентированных API можно использовать библиотеку в автоматических тестах, чтобы изменить результаты HTTP-запросов, добавив дополнительное время на обратное путешествие или изменив ответ (например, код состояния HTTP, заголовки, тело или другие факторы). Это позволяет детерминированное тестирование подмножества условий сбоя для временных сбоев и других типов сбоев.

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

Управление конфигурациями политики повторных попыток

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

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

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

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

Ведение журнала и отслеживание временных и непереходящих ошибок.

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

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

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

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

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

Управление операциями, которые постоянно завершаются сбоем

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

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

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

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

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

Другие рекомендации

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

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

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

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

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