Хотя статьи эти написаны в первую очередь для разработчиков, аналитикам, особенно проектирующим API, тоже нужно разбираться в теме. Особенно критичной тема перезапросов становится при наличии множества экземпляров клиента (фронтового клиента или клиента-микросервиса) и высокой нагрузки. Если у вас API используется только между двумя экземплярами системы раз в сутки — то вам и заморачиваться особо не нужно (и вообще это больше похоже на ETL, а не на API).
Впрочем, в любом случае стоит рассчитывать, что удаленный сервер упадет. Вопросы только — когда и какова будет продолжительность недоступности.
Даже если сервер не упадет совсем, а просто замедлится — начнет расти число активных клиентов по Закону Литтла: число клиентов в очереди равно интенсивности запросов умноженное на среднее время обработки запроса. Через некоторое время сервер просто перестанет отвечать: все доступные соединения будут заняты. Если клиент сам обрабатывает запрос другого сервиса — что бывает очень часто в микросервисной архитектуре — задержка начнет распространяться по всей системе в обратную сторону, и ляжет всё.
Как сказано в статье от AWS:
Рассмотрим систему, в которой вызов пользователя создает пятиуровневый стек вызовов сервиса. Он предусматривает отправку в итоге запроса к базе данных, а также три повторные попытки на каждом уровне. Что происходит, когда в базе данных начинают возникать ошибки запросов вследствие нагрузки? Если на каждом уровне выполняются свои повторные попытки, нагрузка на базу данных увеличится в 243 раза, что сделает ее восстановление маловероятным.
Какие моменты в статье про Васю и на что нужно обратить внимание, когда в проектируете перезапросы:
1. Максимальное число перезапросов (в какой-то момент нужно остановиться и выдать ошибку)
2. Промежутки между запросами: равные или увеличивающиеся (exponential backoff)? Кроме экспоненциального роста промежутка бывают ещё увеличивающиеся по последовательности Фибоначчи.
3. Максимальное время, пока мы вообще делаем перезапросы.
4. Jitter — случайная задержка между запросами, чтобы распределить нагрузку от разных экземпляров клиентов.
5. Circuit Breaker — "размыкатель" — отключение ретраев при превышении числа неисполненных запросов определенного порога, например — 20%
6. Retry Budget — на перезапросы выделяется ограниченный "бюджет", доля от общего числа запросов. В статье от AWS упомянут "алгоритм маркерной корзины", который работает примерно так: от каждого успешного запроса клиент "откладывает" в "корзину" часть маркера/токена, например, 0.1. Для того, чтобы сделать перезапрос, клиент должен "взять" из корзины целый токен (соотношение 1/10). Если целых токенов в корзине нет — перезапрос не на что сделать.
Также в статье описана техника deadline propagation — когда клиент передает серверу в заголовке запроса значение таймаута, после которого он будет делать ретрай. Если сервер понимает, что не укладывается в таймаут, он сразу прерывает выполнение запроса и возвращает ошибку, причем учитывает ожидание ответа от следующего сервера в цепочке.
P.S.: Кроме статьи про ретраи, про Васю есть ещё статья, в которой он проектирует API, там тоже много интересного.