Переполнение памяти

  • Автор темы Vovanisa
  • Дата начала

Vovanisa

Guest
Переполнение памяти

1. Есть сервер в локальной сети (Linux. Apache. Оперативка 1Gb. Диск 3 терабайта. 2 проца) с файловым архивом кин размером от 400Mb до 1.5 Gb.
2. Apach находится /data/vhosts/htdocs
Фильмы за пределами http в /data/download
3. Чтобы скачать фильм зарегенный юзер проверяется скриптом на наличие WMZ на счету и т.д. и если у него положительный баланс, то со счета снимается N-ая копеечка и он забирает себе файл с фильмом таким скриптом на PHP
$fp = fopen($File_Server, "rb");
$filesize=filesize($File_Server);
if($fp){
header("Content-Description: File Transfer");
header("Accept-Ranges: bytes");
header("Content-Length: ".$filesize);
header("Content-Disposition: attachment; filename=".$file_avi);
header("Content-Type: application/x-force-download; name=\"$file_avi\"");
header("Content-Transfer-Encoding: binary");
ob_start();
while(!feof($fp)){
$buffer = fread($fp,1024*256);
echo $buffer;
flush();
ob_flush();
}
ob_end_flush();
ob_end_clean();
fclose($fp);
}
На сервере находится порядка 100 юзеров и при одновременной скачке происходит переполнение оперативки, бешеный свап и сервер удачно "затормаживается и ложится на бочок"

Прошу помочь где проблема в скрипте ?
 

SiMM

Новичок
> ob_start();
Это вообще зачем?
[m]fpassthru[/m]
[m]readfile[/m]
PS: правда разумнее сделать поддержку Range
 

Vovanisa

Guest
Автор оригинала: SiMM
> ob_start();
Это вообще зачем?
[m]fpassthru[/m]
[m]readfile[/m]
Это конечно чудово, но не забывай что размер файла составляет 1,5 Гига.
 

Profic

just Profic (PHP5 BetaTeam)
Vovanisa
Если ты ще не понял, то как раз вот это:
ob_start();
echo $buffer;
ob_flush();
и сжирает твою память.
А то, что посоветовал SiMM, и есть правильный способ делать скачку. И поддержка докачки на таких объемах просто необходима. Иначе юзеры все разбегутся.

-~{}~ 06.08.05 12:43:

И вообще такое впечатление что автор топика не читал мануал на функции которыми пользуется, да и на те, что предложил SiMM тоже.
 

Vovanisa

Guest
Спасибо. Сейчас проверю загрузку сервера.
И вопрос к Profic - где посмотреть о докачке ?
 

SiMM

Новичок
> И вопрос к Profic - где посмотреть о докачке ?
На форуме.
download докачк*
 

Vovanisa

Guest
Спасибо Simm и Profic в помощи. Но возникла новая проблема - при скачивании архива rar или zip он оказывается битым

-~{}~ 06.08.05 17:14:

Прошу всех профи найти ошибки:

$file_extension = strtolower(substr(strrchr($Tmpp_files,"."),1));
switch( $file_extension ) {
case "exe": $ctype="application/octet-stream"; break;
case "zip": $ctype="application/zip"; break;
case "rar": $ctype="application/rar"; break;
case "mp3": $ctype="audio/mpeg"; break;
case "mpg": $ctype="video/mpeg"; break;
case "avi": $ctype="video/x-msvideo"; break;
default: $ctype="application/x-force-download";
}


$size=filesize($File_Server);
$ftime = date("D, d M Y H:i:s T", filemtime($File_Server));
header("Content-Type: $ctype");
header("Content-Disposition: attachment; filename=".$Tmpp_files);
header("Content-Transfer-Encoding: binary");


header("Pragma: public");
header("Expires: 0");
header("Cache-Control:");
header("Cache-Control: public");

header("Accept-Ranges: bytes");
header("Content-Description: File Transfer");
header("Last-Modified: $ftime");

//check if http_range is sent by browser (or download manager)
if(isset($_ENV['HTTP_RANGE'])) {
list($a, $range)=explode("=",$_ENV['HTTP_RANGE']);
str_replace($range, "-", $range);
if ($range) {
header("HTTP/1.1 206 Partial Content");
$size2=$size-1;
header("Content-Range: $range$size2/$size");
$new_length=$size2-$range;
header("Content-Length: $new_length");
$fp = fopen($File_Server, "rb");
fseek($fp, $range);
$fd = fread($fp, filesize($File_Server));
fclose($fd);
}
}else{
header("HTTP/1.1 200 OK");
$size2=$size-1;
header("Content-Range: bytes 0-$size2/$size");
header("Content-Length: ".$size2);
$fd=readfile($File_Server);
}


fpassthru($fd);
flush();
exit;
 
Сверху