Постоянный/keepalive HTTP с библиотекой PHP Curl?
Я использую простую библиотеку PHP для добавления документов в индекс SOLR через HTTP.
В нем задействовано 3 сервера:
- Ящик PHP, в котором выполняется задание индексирования
- Ящик базы данных, в котором индексируются данные.
- Коробка solr.
В 80 документах/сек (из 1 миллиона документов) я замечаю необычно высокую скорость прерывания на сетевых интерфейсах на PHP и solr-боксах (2000/sec, что больше, графики почти идентичны) когда частота прерываний на ящике PHP увеличивается, она также накладывается на поле Solr), но гораздо меньше - на поле базы данных (300/sec). Я предполагаю, что это просто потому, что я открываю и повторно использую одно соединение с сервером базы данных, но каждый запрос Solr открывает новое HTTP-соединение через cURL, благодаря тому, как написана клиентская библиотека Solr.
Итак, мой вопрос:
- Можно ли сделать cURL для открытия сеанса keepalive?
- Что нужно для повторного использования соединения? - Это так же просто, как повторное использование ресурса дескриптора cURL?
- Нужно ли устанавливать какие-либо специальные опции cURL? (например, сила HTTP 1.1?)
- Есть ли какие-либо проблемы с подключением cURL keepalive? Этот script работает в течение нескольких часов; я смогу использовать одно соединение или мне нужно будет периодически подключаться?
Ответы
Ответ 1
Документация cURL PHP (curl_setopt):
CURLOPT_FORBID_REUSE
- TRUE
, чтобы заставить соединение с явно закрытым когда он завершил обработку, и не объединяются для повторного использования.
Итак:
- Да, на самом деле он должен повторно использовать соединения по умолчанию, если вы повторно используете дескриптор cURL.
- по умолчанию, cURL обрабатывает постоянные соединения сам по себе; если вам нужны специальные заголовки, проверьте CURLOPT_HTTPHEADER
- сервер может отправить тайм-аут keep-alive (с установкой Apache по умолчанию, это 15 секунд или 100 запросов, в зависимости от того, что наступит раньше) - но cURL просто откроет другое соединение, когда это произойдет.
Ответ 2
Curl отправляет заголовок keep-alive по умолчанию, но:
- создайте контекст, используя
curl_init()
без каких-либо параметров.
- сохранить контекст в области, где он выдержит (а не локальный var)
- использовать параметр
CURLOPT_URL
для передачи URL-адреса в контекст
- выполнить запрос с помощью
curl_exec()
- не закрывайте соединение с
curl_close()
очень простой пример:
function get($url) {
global $context;
curl_setopt($context, CURLOPT_URL, $url);
return curl_exec($context);
}
$context = curl_init();
//multiple calls to get() here
curl_close($context);
Ответ 3
-
На сервере, к которому вы обращаетесь, keep-alive должен быть включен и максимальные запросы keep-alive должны быть разумными. В случае Apache обратитесь к apache docs.
-
Вы должны повторно использовать один и тот же контекст cURL.
-
При настройке контекста cURL включите keep-alive с таймаутом в заголовке:
curl_setopt($curlHandle, CURLOPT_HTTPHEADER, array(
'Connection: Keep-Alive',
'Keep-Alive: 300'
));
Ответ 4
Если вам не нужен ответ от запроса, вы можете сделать это асинхронно, но вы рискуете перегрузить свой индекс SOLR. Я сомневаюсь, однако, SOLR довольно чертовски быстро.
Асинхронные вызовы PHP?