2

我有一个用 php 编写的下载网站,可以使用 curl 从远程服务器下载,但问题是 httpd 连接没有终止,它们仍然处于睡眠模式,这正在杀死我的服务器资源,这是顶部输出

顶部 - 20:55:36 上升 4 天,13:41,1 个用户,平均负载:1.99、5.73,  
10.47 任务:总共 2207 个,5 个正在运行,2202 个睡眠,0 个停止,0 个僵尸 CPU:24.1%us,1.5%sy,0.0%ni,73.3%id,0.0%wa,0.0%hi,1.1%si,  
0.0%st 内存:总计 4045976k,已使用 4000712k,可用 45264k,1448k 缓冲区交换:总计 8385920k,已使用 2353584k,可用 6032336k,缓存 30336k

我使用它跟踪了一个 pidstrace -p 22254 -s 80 -o /tmp/debug.lighttpd.txt我得到了这个我不确定的输出,但它似乎正在轮询和轮询

clock_gettime(CLOCK_MONOTONIC, {10396, 471413333}) = 0
poll([{fd=24, events=POLLOUT}], 1, 725) = 0 (Timeout)
clock_gettime(CLOCK_MONOTONIC, {10397, 196905333}) = 0
clock_gettime(CLOCK_MONOTONIC, {10397, 196955333}) = 0
poll([{fd=24, events=POLLOUT}], 1, 1000) = 0 (Timeout)
clock_gettime(CLOCK_MONOTONIC, {10398, 197890333}) = 0
clock_gettime(CLOCK_MONOTONIC, {10398, 197937333}) = 0
poll([{fd=24, events=POLLOUT}], 1, 1000) = 0 (Timeout)

是否有我丢失的任何 http 标头,或者无论如何要终止这些连接,有什么想法吗?

这是我正在使用的 php 代码,这是它的重要部分

header('Content-Disposition: filename='.$fileName);
header("Content-Type: application/octet-stream\n"); 
header("Connection: close\n");
header("Accept-Ranges: bytes");
header("Content-Range: bytes 0-$size2/$size"); 
header("Content-Length: ".$size);

while($start_range <= $end_range) { 
if (connection_status()!=0) return(false); 
if(($start_range + 999999) > $end_range) $range = $start_range.'-'; 
else $range = $start_range.'-'.($start_range + 999999); 
$ch = curl_init(); 
curl_setopt($ch, CURLOPT_URL, $fileLocation); 
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
if ($cookie != false) curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie); 
if ($refurl != false) curl_setopt($ch, CURLOPT_REFERER, $refurl); 
curl_setopt($ch, CURLOPT_RANGE,$range); 
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1'); 
curl_exec($ch); 
curl_close($ch);
$start_range +=1000000; 

flush(); 
ob_flush();
ob_end_flush();
}
4

1 回答 1

0

所以问题出在http头保持活动状态,连接保持活动状态导致了麻烦,这就是我修复它的方法。

我没有每次都启动和关闭 curl,而是初始化一个 curl,然后我发送定义 keep-alive 和 keep-alive 时间的 http 标头。这解决了我的问题

$ch = curl_init(); 
while($start_range <= $end_range) { 
    if (connection_status()!=0) return(false); 
    if(($start_range + 999999) > $end_range) $range = $start_range.'-'; 
    else $range = $start_range.'-'.($start_range + 999999); 
    curl_setopt($ch, CURLOPT_URL, $fileLocation); 
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Connection: Keep-Alive',
    'Keep-Alive: 300',
    'Cache-Control: no-cache'
    ));
    if ($cookie != false) curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie); 
    if ($refurl != false) curl_setopt($ch, CURLOPT_REFERER, $refurl); 
    curl_setopt($ch, CURLOPT_RANGE,$range); 
    curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1'); 
    $content = curl_exec($ch); 
    echo $content;
    unset($content);
    $start_range +=1000000;     
    flush(); 
    ob_flush();
}
curl_close($ch);
于 2012-07-30T17:49:07.077 回答