Ограничить количество запросов CFHTTP, отправляемых каждые x секунд
Я делаю приложение, которое будет постоянно отправлять запросы CFHTTP на сервер для поиска элементов, а также отправлять дальнейшие запросы CFHTTP для выполнения действий с любыми возвращенными результатами.
Проблема, с которой я сталкиваюсь, заключается в том, что максимальный порог сервера составляет 3 запроса в секунду, и даже когда я пытаюсь реализовать неактивный вызов каждые 4 миллисекунды, он не работает должным образом, поскольку, хотя и задерживается, запросы CFHTTP могут стоять в очереди если для возврата требуется пара секунд, то он пытается отправить несколько в одну и ту же секунду, вызывая превышение порога.
Есть ли способ, которым я могу гарантировать, что никогда не будет более 3 активных запросов CFHTTP?
2 ответа
Если вы ограничиваете одновременные запросы, то применяется первая часть этого ответа. Если вы хотите ограничить количество запросов в секунду, то применяется бит в конце. Вопрос вроде задает обе вещи.
Если я правильно понимаю, у вас есть несколько потоков (либо как запросы CF обрабатываются, либо потоки, которые CF создает сам), которые все должны совершать вызовы в один и тот же домен с ограниченной скоростью. Что вам нужно, так это центральный способ координации доступа в сочетании с хорошим способом управления выполнением программы.
Я не знаю каких-либо нативных ограничений, которые CF мог бы поддерживать (я был бы рад оказаться ошибочным), поэтому вам, вероятно, придется применять свои собственные. Дешевый и неприятный способ сделать это - увеличить и уменьшить allowed_conenctions
переменная в долгоживущей области, такой как аппликация. Недостатком является то, что вы должны осуществлять проверку повсеместно и что, если нет свободных соединений, вам придется как-то подождать.
На самом деле у вас есть пул ресурсов (разрешенных HTTP-соединений), и я предполагаю, что вы хотите, чтобы ваш код ждал, пока соединение не станет свободным. CF уже делает подобные вещи для соединений с базой данных.
В вашем случае на самом деле нет необходимости хранить что-либо в пуле (поскольку HTTP-соединения не являются долгоживущими), кроме разрешения на использование ресурса. Java предоставляет класс, который должен предоставить то, что вам нужно, семафор.
Я не пробовал, но теоретически, что-то вроде приведенного ниже фрагмента должно работать:
//Application.cfc:onApplicationStart()
application.http_pool = CreateObject("java","java.util.concurrent.Semaphore").init(3)
//Meanwhile, elsewhere in your code
application.http_pool.acquire()
//Make my HTTP call
application.http_pool.release()
Вы могли бы даже обернуть объект HTTP, чтобы обеспечить эту функциональность, без необходимости каждый раз использовать получение / выпуск, что сделало бы его более надежным.
РЕДАКТИРОВАТЬ Если вы хотите ограничить скорость, посмотрите на RateLimiter от guava, который имеет тот же общий интерфейс, что и семафор выше, но реализует ограничение скорости для вас. Вам нужно добавить guava в путь к классам ColdFusion, или использовать JavaLoader, или использовать CF10, который имеет встроенные средства загрузки классов.
Я думаю, вам нужно будет реализовать какой-то виджет регистрации как часть вашего процесса. Журнал будет отслеживать частоту запросов. Если порог не достигнут, вы просто пропустите эту итерацию вызова CFHTTP. Я имею в виду не файловый журнал или журнал базы данных, но что-то реализованное в приложении или даже запрос объема в зависимости от вашей реализации. Нет никакого способа ограничить сам CFHTTP. По сути, это очень упрощенная оболочка библиотеки Java HTTP, которая затем направляется прямо в основную операционную систему.