Ограничение скорости исходящих запросов в Java, но с динамической скоростью

Я создаю приложение, которое включает парсер общедоступного API. Я хочу ограничить скорость своих запросов, но не фиксированной скоростью, а динамической рандомизированной скоростью, которая изменяется между запросами и попадает в определенный диапазон, то есть я могу установить минимальную и максимальную задержку между запросами.

Я также не хочу блокировать текущий поток.

Я исследовал алгоритмы Guava Ratelimiter, RatelimitJ и Token bucket, но, глядя на документы, я не понимаю, как что-то из этих вещей может достичь того, чего я хочу.

Пример желаемого эффекта на мои запросы при диапазоне ограничения скорости 250-350 мс:

  • Сделать заявку №1
  • подождите 321 мс
  • Сделать заявку №2
  • подождите 259 мс
  • Сделать заявку №3
  • подождите 337 мс
  • ...

person Sam    schedule 17.06.2019    source источник


Ответы (1)


Вам не нужно смотреть за пределы JDK. Вы можете использовать java.util.concurrent.ScheduledExecutorService для выполнения вызова после определенной задержки в отдельном потоке. Чтобы использовать это, вам нужно будет реализовать java.util.concurrent.Callable или java.lang.Runnable для кода, который выполняет вызов API.

    ScheduledExecutorService service = Executors.newScheduledThreadPool(1);
    Callable apiCaller = ...;

Чтобы сделать вызов так, чтобы он выполнялся после определенной задержки, вы отправляете его следующим образом:

    service.schedule(apiCaller, delay, TimeUnit.MILLISECONDS);

Чтобы получить случайную задержку, вам просто нужно использовать java.util.Random.

        Random random = new Random();

Random может предоставить вам ограниченное целое число. Поэтому, если вы передадите ему допустимый диапазон, а затем добавите, а затем добавьте минимум, вы получите случайное число между минимальным и максимальным, которое вы хотите.

   int minimumDelay = 250;
   int maximumDelay = 350;       
   int delay = random.nextInt(maximumDelay - minimumDelay) + minimumDelay;
person Marc G. Smith    schedule 17.06.2019