Паттерны обработки сбоев
Зачем
Cбои разделяют:
- временные
- долгосрочные
- окончательные
Регистрируйте и отслеживайте временные и не временные ошибки для мониторинга:
- увеличения числа и частоты возникновения сбоев
- среднего числа повторных попыток
- общего времени, затрачиваемого на успешное выполнение операций
Rate limit
Логика повторения (Retry Logic, Retry Policy)
- Повтор инициируется ИС\клиент потребитель (браузером, другим микросервисом и так далее) с учетом реализации Идемпотетности
- число повторных попыток и интервал между ними ограничен общим максимальным временем для операции\процесса
- типы интервалов:
- Экспоненциальная задержка
- Интервалы с приращениями
- Постоянные интервалы
- Немедленный повтор
- Случайный выбор
- типы интервалов:
- В общем случае используйте стратегию
- экспоненциальной задержки для фоновых операций
- стратегии немедленного повтора или постоянных интервалов для интерактивных операций
- паттерны RMQ failure
Идемпотентность
- Повтор инициируется ИС\клиент потребитель (браузером, другим микросервисом и так далее), который не знает, была ли операция сбойной до или после обработки запроса
- ИС источник должна уметь обрабатывать идемпотентность.
- Например, когда вы повторяете операцию покупки, то вы не должны дублировать взимание средств с покупателя. Вам поможет использования уникального ключа идемпотентности для каждой транзакции.
Fail fast
Выбросить ошибку как можно раньше подходы:
- Лимит на объемы любых запрашиваемых клиентом данных
- Обязательный таймаут на все удаленные операции
- Для баз данных и на клиенте и на сервере, т.к прерванный запрос может продолжать выполнение
- Ограничение частоты обращений к серверу, а после превышения - 429 error code
- Ограничение количества открываемых входящих / исходящих соединений
- Ограничение размера задействованных пулов потоков под каждый тип операций
- Валидация аргументов запроса к сервису на стороне клиента (запрос все равно будет отвергнут, но мы сохраним время на удаленных вызов и пропускную способность сети)
Применение парадигмы «быстрого сбоя» fail fast в микросервисах посредством таймаутов является антипаттерном, которого следует избегать. Вместо таймаутов можете применять шаблон circuit-breaker, который зависит от статистики успешных/сбойных операций.
Каскадные сбои
- В микросервисной архитектуре нужно подготовить свои сервисы сбоить быстро и раздельно.
- Быстрый сбой компонентов нужен потому, что мы не хотим ждать, пока закончатся таймауты сломанных инстансов. Ничто так не раздражает, как зависший запрос и не отвечающий на ваши действия интерфейс. Это не только потерянные ресурсы, но и испорченный пользовательский опыт.
- Сервисы вызывают друг друга по цепочке, поэтому нужно уделять особое внимание предотвращению повисания операций, не допуская накопления задержек.
Автоматы замыкания (Circuit Breakers)
- Таймауты можно использовать для ограничения продолжительности операций. Они могут предотвратить подвисание операций и поддерживать реагирование системы на ваши действия. Использование в микросервисной архитектуре статичных, тонко настраиваемых таймаутов является антипаттерном, поскольку речь идёт о высокодинамичной среде, в которой практически невозможно подобрать подходящие временные ограничения, хорошо работающие в любых ситуациях.
- Автомат замыкания открывается, когда в течение короткого времени несколько раз возникает ошибка определённого типа. Открытый автомат предотвращает передачу запросов
- Не все ошибки должны инициировать автомат замыкания. Например, вы наверняка захотите пропустить ошибки на стороне клиента вроде запросов с кодами 4хх, но при этом отреагировать на серверные сбои с кодами 5хх.
- Использование методов Isolate (размыкает цепь и сохраняет ее в таком состоянии) и Reset (снова замыкает цепь). Таким образом, можно создать служебную конечную точку HTTP, которая напрямую вызывает методы Isolate и Reset политики. Такую конечную точку HTTP с надлежащей защитой можно также использовать в рабочей среде для временной изоляции подчиненной системы, например, если ее необходимо обновить. Кроме того, с ее помощью можно размыкать цепь вручную для защиты подчиненной системы, если есть подозрения на ее неисправность.