(java || kotlin) && devOps
374 subscribers
6 photos
1 video
7 files
318 links
Полезное про Java и Kotlin - фреймворки, паттерны, тесты, тонкости JVM. Немного архитектуры. И DevOps, куда без него
Download Telegram
Всем привет!

Сегодня расскажу про такую штуку, как rate limiters.
Как следует из названия это компонент для ограничения числа запросов в интервал времени.
Может возникнуть вопрос - причем здесь Java? Да, обычно такие штуки разворачивают на инфраструктуре - например, в k8s или nginx.
Если так можно сделать - так и нужно делать)
Когда так сделать не получится:
1) алгоритм ограничения числа запросов нестандартный, поэтому нужна Java, чтобы его запрограммировать)
2) нужна возможность продвинутого мониторинга числа пропущенных и отбитых запросов
3) при изменении параметров rate limiting нужна умная ребалансировка. Т.е. нельзя просто сбросить счетчики в ноль, т.к. это приведет к падению сервиса, который защищает rate limiter.
4) ну и наконец нет подходящей инфраструктуры

Второй вопрос - в каких кейсах это может понадобиться:
1) не уронить стоящий за вами сервис
2) приоритизировать какие-то запросы вашего API по сравнению с другими чтобы не упасть самому
3) ограничить число запросов по тарифному плану клиента

Вот неплохая статья про существующие алгоритмы rate limiting https://habr.com/ru/post/448438
Неплохая библиотека для Java - Bucket4J https://github.com/bucket4j/bucket4j
Развивается порядка 8 лет, к слову разработчики из России.
Вот хорошее видео от разработчиков с примерам настройки - https://www.youtube.com/watch?v=OSNFNxgZZ3A
В простых случаях можно использовать Resilience4j, удобно со Spring Boot посредством аннотаций https://www.baeldung.com/spring-boot-resilience4j Resilience4j библиотека более широкого профиля, отвечает за отказоустойчивость, см. детали в статье

#java #libraries #highload #interview_question #rate_limiters #reliability_patters
👍6
На Highload услышал упоминание про timeout propagation и вспомнил, что давно хотел эту тему поднять.
В чем суть - где-то настроен timeout, и для того, чтобы upstream сервисы знали про него - мы передаём его в заголовках, также как и traceId. Наилучшее место для создания этих заголовков - входной шлюз. Или API Gateway - именно так сделали в Avito. Передать таймуат можно двумя способами - как длительность, X-Timeout = 5s или как время - X-Deadline: 06.12.2024 14:55:45. Второй вариант проще обрабатывать на upstream серверах, т.к. не нужно вычислять сколько из первоначального таймаута осталось, но требуется синхронизация времени на всех серверах.

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

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

#reliability #timeout