Вызов метода лимита в секунду (откажитесь, когда достигнут предел) - PullRequest
4 голосов
/ 18 мая 2011

У меня есть метод, который выполняет некоторые операции ввода-вывода, и я хотел бы ограничить количество обращений (в секунду) к этому методу, чтобы сервер не получал пакеты параллельных запросов, которые он не может обработать.

Если бы требование приходило без «в секунду», я мог бы просто использовать стек (в основном просто счетчик) и offer() при запуске запроса и poll() при выполнении. С требованием «в секунду» мне как-то нужно очистить слоты в стеке, которые старше указанного промежутка времени.

Как мне сделать это правильно? Очевидно, структура должна быть поточно-ориентированной.

Спасибо за ваше время!

Ответы [ 3 ]

3 голосов
/ 18 мая 2011

Вы можете использовать очередь, но с некоторыми изменениями. Всякий раз, когда вы хотите добавить в очередь (метод вызывается), вы проверяете, сколько элементов в нем и когда они были добавлены. Все элементы, которые были вставлены более одной секунды назад, могут быть удалены. Сравните количество оставшихся элементов со скоростью в секунду, и вы решите, следует ли отклонить выполнение метода или нет. Это может быть немного сложнее, если вы собираетесь использовать блок метода вместо отклонения.

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

2 голосов
/ 18 мая 2011

Посмотрите на этот вопрос .Ответ в равной степени применим к этой проблеме, даже если вопрос сформулирован довольно по-другому.

Признаюсь, я нахожу его немного загадочным, но он прекрасно работает.

0 голосов
/ 18 мая 2011

Похоже, вам нужно отделить работу ввода-вывода от запрашивающего потока и вместо этого разгрузить ее в пул потоков с заданным размером. Таким образом, вы можете явно контролировать количество потоков, выполняющих ввод / вывод одновременно.

ExecutorService pool = Executors.newFixedThreadPool(10);

public void myMethod() {

  pool.submit(new Runnable() {
    public void run() {
      //Do IO work here
    }
  });

}

В этом примере никогда не будет более 10 потоков, выполняющих работу ввода-вывода. Это не ограничивает количество запросов в секунду, но контролирует параллелизм, вероятно, лучший способ регулирования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...