Sobes.tech
Назад к вопросам
Senior
6

Как реализовать rate limiting для внешнего API с ограничением по RPS? Чем отличаются виртуальные потоки/корутины от системных потоков?

Компании, где спрашивали
Ozon ФинтехOzon Финтех

Ответ от нейросети

sobes.tech AI

Для реализации rate limiting по RPS (requests per second) к внешнему API в Java можно использовать различные подходы:

  1. Token Bucket или Leaky Bucket — классические алгоритмы ограничения частоты запросов. Например, с помощью библиотеки Guava RateLimiter:
import com.google.common.util.concurrent.RateLimiter;

RateLimiter rateLimiter = RateLimiter.create(10.0); // 10 запросов в секунду

public void callApi() {
    rateLimiter.acquire(); // блокирует, пока не будет разрешено
    // вызов внешнего API
}
  1. Собственная реализация с использованием ScheduledExecutorService — можно считать количество запросов за секунду и блокировать или откладывать вызовы.

  2. Использование сторонних библиотек — например, Resilience4j, которая поддерживает rate limiting и другие паттерны устойчивости.


Отличия виртуальных потоков (корутин) от системных потоков:

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

  • Виртуальные потоки (например, Project Loom в Java) — легковесные потоки, управляемые JVM, а не ОС. Они позволяют создавать тысячи и миллионы параллельных задач с низкими затратами памяти и переключения контекста.

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

Ключевые отличия:

  • Виртуальные потоки и корутины более эффективны по памяти и CPU.
  • Виртуальные потоки интегрируются с существующим API потоков Java.
  • Корутины требуют поддержки на уровне языка и компилятора.

Таким образом, виртуальные потоки позволяют масштабировать параллелизм без значительных накладных расходов, что особенно полезно для IO-bound задач, таких как вызовы внешних API.