Хорошая статья, объясняющая на простых примерах практики для взаимодействия с сервером, который отдает ошибки. Наверняка, вы сталкивались с ситуацией, когда сервер иногда отвечает ошибкой, но если повторить запрос - то ответит корректно. Решение на поверхности - просто влепить retry. Что может пойти не так?
Статья как раз и объясняет что может пойти не так. Если коротко, то retry может привести к тому, что нагрузка на сервер вырастет и он перестанет справляться с обработкой запросов. После этого количество ошибок возрастет, количество retry увеличится, что приведет к еще более печальным результатам. В статье рассказывается как правильно делать обращения к нестабильному серверу
Первая практика: retry. Если все клиенты будут использовать retry с одинаковым таймаутом между запросами, то если серверу станет плохо - ретраи его добьют. Чтобы этого не случилось, используют exponential backoff retry - это когда ретраи делаются не через фиксированные отрезки времени, а эти отрезки увеличиваются. Грубо говоря, если сервер не смог ожить за первые 2 быстрых ретрая, то вряд ли он оживет в ближайшее время, поэтому есть смысл увеличивать с каждой попыткой интервал между попытками.
Если все клиенты будут ретраить с одинаковыми таймаутами, то нагрузка на сервер будет происходить волнами. Чтобы это устранить, добавляют jitter - случайную задержку к интервалам между ретраями.
Но в целом, при долгом отказе сервера, даже "умные" ретраи не спасают - они лишь откладывают пик нагрузки. Поэтому применяют и другие практики: Retry circuit breaker и Retry budget.
Практика Retry circuit breaker говорит о том, что ретраи допускается делать если количество ошибок от сервера не превышает порог. Если превышает - мы считаем что сервис немножко нездоров и долбить его ретраями - значит делать хуже
Практика Retry budget говорит о том, что ретраев не должно быть больше определенного порога от количества успешных запросов. Например, не больше 10% от запросов.
Но и это еще не все. Еще существует практика deadline propagation. Это когда клиент в запросе передает значение таймаута и сервер, получая запрос на обработку из очереди обработки, может принять решение - есть ли смысл его обрабатывать. Или прекратить обрабатывать запрос, ответ на который клиент уже не ждет.
В общем, крутая статья с хорошими примерами и графиками про основные паттерны борьбы с нагрузкой на нестабильный сервер