【问题标题】:Server comes to a standstill when using PHP cURL使用 PHP cURL 时服务器停止
【发布时间】:2015-03-21 13:54:07
【问题描述】:

我有一个基本的抓取工具,它访问一个 URL,检查指向另一个给定 URL 的链接,并返回任何找到的链接的锚文本。抓取工具还会返回每个链接的源页面和目标页面的 http 状态。

刮板正在运行 WAMP 的专用 Windows 7 机器上运行。 8 gigs 的 RAM(内存不是问题,因为刮板甚至没有使用 .ini 文件集可用的 30% 的内容,以便尽可能多地使用)。由于它是代表企业运行的,因此互联网连接是一条固定的 IP 光纤线路,传输速度约为 50mb)。

我使用的 curl 包装器是 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。

我的问题是,当爬虫第一次运行时(大约 10 分钟处理 1000 个 URL 左右),访问服务器变得有点慢。但是当第二次运行时,服务器变得无响应,并且无法通过该机器进行任何互联网活动。

让我感到困惑的是,当我观看资源监视器时,第一次运行时活动 TCP 连接的数量在 300/500 之间移动,然后在那之后不会超过 10 个活动连接。

真正奇怪的是,资源监视器显示只有 10 个 TCP 连接处于活动状态/可用(通过迷你图显示),但 TCP 连接信息选项卡显示 httpd.exe 正在运行数百个连接 - 全部在相同的 PID 下使用不同的端口。

为什么在 Apache httpd.exe 进程仍在占用端口的情况下,正在使用的活动 TCP 连接数量大幅减少?

什么定义了 Windows PC 可以拥有多少活动 TCP 连接,以及 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();
    }
}

【问题讨论】:

  • 您应该包括可能相关的其他详细信息,例如操作系统、Apache、PHP 和 cURL 版本。不确定它是否会有所作为,但您可以尝试直接通过 CLI 而不是 Apache 运行。
  • 该示例代码中也没有与curl_multi_ 相关的代码?
  • @JeremiahWinsley 添加了信息。
  • @RiggsFolly 我包含了实际执行 cURL GET 请求的方法。
  • 需要更多信息。你的硬件到底是什么。 i386 win32 很少告诉我们有关硬件的信息。什么Windows版本?经验?赢7?赢8?赢2008服务器?有多少内存?您的互联网连接速度有多快?您是否在托管设施的专用 Windows 机器上运行?还是在家里?如果您在家中从盒子中刮擦,请不要。在专用的 Windows 服务器上执行此操作。您最不想要的就是您的 ISP 关闭您的帐户。

标签: php curl tcp wamp


【解决方案1】:

仔细检查 curl-Request 的超时时间(300 秒)与 PHPScript 的超时时间(http://php.net/manual/de/function.set-time-limit.php

如果您的脚本在 cURL-Timeout 之前停止,您将永远不会得到响应。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-28
    • 1970-01-01
    相关资源
    最近更新 更多