使用PHP cURL时服务器停止运行

时间:2015-01-22 16:57:28

标签: php curl tcp wamp

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

刮刀正在运行WAMP的专用Windows 7机器上运行。 8 GB的内存(内存不是问题,因为刮刀甚至不使用.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下但具有不同的端口。

为什么使用的活动TCP连接数量大幅减少,而Apache httpd.exe进程仍然保留在端口上?

什么定义了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();
    }
}

1 个答案:

答案 0 :(得分:0)

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

如果您的脚本在cURL-Timeout之前停止,您将永远不会收到回复。