Сервер останавливается при использовании PHP cURL

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

Скребок запускается с выделенной машины Windows 7, на которой работает WAMP. 8 гигабайт оперативной памяти (память в этом не проблема, поскольку скребок даже не использует 30% того, что доступно с файлом .ini, установленным для использования столько, сколько он хочет). Поскольку он работает от имени бизнеса, интернет-соединение представляет собой фиксированную волоконно-оптическую линию IP, скорость передачи которой составляет около 50 Мб).

Я использую упаковку для завитков https://github.com/php-curl-class/php-curl-class, и это выполняется через стек WAMP (Apache 2.4.4, PHP 5.4.16) на довольно мощной машине.

Я использую версию cURL:

'version_number' => int 466432
'age' => int 3
'features' => int 3005
'ssl_version_number' => int 0
'version' => string '7.30.0' (length=6)
'host' => string 'i386-pc-win32' (length=13)
'ssl_version' => string 'OpenSSL/0.9.8y' (length=14)
'libz_version' => string '1.2.7' (length=5)

Скребок разбивает URL-адреса на группы по 175, а затем пропускает их через мульти-вывод cURL, выводя результаты в CSV.

Моя проблема заключается в том, что когда скребок запускается в первый раз (около 1000 URL-адресов обрабатывается примерно за 10 минут), доступ к серверу становится немного медленным. Но при повторном запуске сервер перестает отвечать на запросы, и через эту машину невозможно выполнять какие-либо действия в Интернете.

Что меня смущает, так это то, что когда я смотрю Resource Monitor, количество активных TCP-соединений перемещается между 300/500 для первого запуска, а затем не будет перемещаться после 10 активных соединений после этой точки.

Что действительно странно, так это то, что монитор ресурсов показывает, что активны / доступны только 10 TCP-подключений (показано на графике спарклайна), но на вкладке информации о TCP-подключениях показано несколько сотен подключений, запущенных httpd.exe — все под одним и тем же PID но с разными портами.

Почему количество используемых активных TCP-соединений так резко сокращается, в то время как процесс Apache httpd.exe все еще удерживает порты?

Что определяет, сколько активных TCP-подключений может иметь Windows-ПК, и как насчет запросов cURL будет эффективно уменьшать это число?

Вот копия функции, выполняющей вызовы cURL:

private function getUrls_curl ($urls = array(), $statusOnly = FALSE)
{
$curl = new \DAMC\modules\_global\curl();

//set some extra options
$curl->setOpt(CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)');
$curl->setOpt(CURLOPT_TIMEOUT, '300');
$curl->setOpt(CURLOPT_SSL_VERIFYPEER, FALSE);

if ($statusOnly === FALSE)
{
$curl->success( array($this, 'parseUrl') );
$curl->error( array($this, 'error') );
}
else
{
$curl->complete( array($this, 'statusOnly') );
$curl->error( array($this, 'statusOnly') );
}

$curl->get($urls);
$curl->close();
}

$curl->get() Метод определен в библиотеке, с которой я связан выше, и выполняет curl_multi следующим образом:

public function get($url_mixed, $data=array())
{
if (is_array($url_mixed))
{
$curl_multi = curl_multi_init();
$this->_multi_parent = true;

$this->curls = array();

foreach ($url_mixed as $url)
{
$curl = new Curl();
$curl->_multi_child = true;
$curl->setOpt(CURLOPT_URL, $this->_buildURL($url, $data), $curl->curl);
$curl->setOpt(CURLOPT_CUSTOMREQUEST, 'GET');
$curl->setOpt(CURLOPT_HTTPGET, true);
$this->_call($this->_before_send, $curl);
$this->curls[] = $curl;

$curlm_error_code = curl_multi_add_handle($curl_multi, $curl->curl);
if (!($curlm_error_code === CURLM_OK)) {
throw new \ErrorException('cURL multi add handle error: ' .
curl_multi_strerror($curlm_error_code));
}
}

foreach ($this->curls as $ch)
{
foreach ($this->_options as $key => $value)
{
$ch->setOpt($key, $value);
}
}

do {
$status = curl_multi_exec($curl_multi, $active);
} while ($status === CURLM_CALL_MULTI_PERFORM || $active);

foreach ($this->curls as $ch)
$this->exec($ch);

}
else
{
$this->setopt(CURLOPT_URL, $this->_buildURL($url_mixed, $data));
$this->setOpt(CURLOPT_CUSTOMREQUEST, 'GET');
$this->setopt(CURLOPT_HTTPGET, true);
return $this->exec();
}
}

1

Решение

Дважды проверьте время ожидания вашего curl-запроса (300 секунд) по сравнению с временем ожидания PHPScript (http://php.net/manual/de/function.set-time-limit.php)

Если ваш сценарий останавливается до истечения времени ожидания cURL, вы никогда не получите ответ.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]