私はApacheサーバー、PHPアプリケーションに大きな問題があります。PHP readfile()は終了せず、Apacheサーバーをハングアップさせます
サーバーは、PHPで動作している非常に高いトラフィックのWebサイトを提供しています。
24時間または48時間ごとに、apacheがハングアップし、ウェブサイトに再びアクセスできるように再起動する必要があります。私はそれをリブートしなければなりません。なぜなら、apacheは許可されたプロセス/サーバ(私にとっては16000)の最大数に達し、他のプロセスはすべてアクティブなので、他のプロセスを解放することはできません。
このサーバーでホストされているWebサイトは、最後にファイルを提供するPHPアプリケーションです。ダウンロードサーバーといいます。
ファイルは、POSTリクエストを送信するフォームを介してブラウザから要求されます。
問題は、この投稿要求は決して終わらないようです(私のサーバーステータスのほぼすべての16000プロセスがPOSTリクエストであることがわかります)。 (私はhrefのリンクとそれらを提供したくない、そうなるように、私は、フォームのPOSTリクエストを使用して提供しています
ファイルは大きなファイル(2Gまで10M)であり、私はPHPののReadFile関数とそれらを提供しますファイルシステム上のどこにファイルが存在するかわかりません)。
phpのreadfileを使用する関数は、最後にexit()を使用しても決して終了しないようです(下記のコードスニペットを参照)。
私は私のPHPコードによって引き起こされ、この終わることのないPOSTリクエストを回避する方法についてはこちらを求めています。私は、POSTファイルの提供方法を維持したい。
まず私のconf:128G RAM :MPMのpreforkの
- Ubuntuのサーバ14.04
- のApache 2.4
私mpm_prefork.confファイル:
<IfModule mpm_prefork_module> StartServers 512 MinSpareServers 512 MaxSpareServers 1024 ServerLimit 16000 # no problem with my server ram MaxRequestWorkers 16000 MaxConnectionsPerChild 10000 </IfModule>
私apache2.confファイル:
... Timeout 300 KeepAlive On MaxKeepAliveRequests 500 KeepAliveTimeout 5 ...
私のPHP。iniファイル:
max_execution_time = 7200
私のApacheのログファイル:私の問題のための興味深い何
そして、私のサーバ・クラス(問題を引き起こしているコード):
class Server { /* the file is served from a remote url source */ public function serveFileFromUrl() { if (empty($_POST)) { return; } $url = $_POST['file_url']; $mime = $_POST['mime']; $name = sanitizeFileName($_POST['name']) . uniqid() . '.' . $mime; $size = $_POST['size']; if (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== false) { // for Internet Explorer if ($mime == 'mp3') { header('Content-Type: "audio/' . $mime . '"'); } else { header('Content-Type: "video/' . $mime . '"'); } header('Content-disposition: attachment; filename="' . $name . '"'); header('Expires: 0'); if ($size !== '') { header('Content-Length: ' . $size); } header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); header("Content-Transfer-Encoding: binary"); header('Pragma: public'); } else { // not for internet Explorer if ($mime == 'mp3') { header('Content-Type: "audio/' . $mime . '"'); } else { header('Content-Type: "video/' . $mime . '"'); } header('Content-disposition: attachment; filename="' . $name . '"'); header('Expires: 0'); if ($size !== '') { header('Content-Length: ' . $size); } header("Content-Transfer-Encoding: Binary"); header('Pragma: no-cache'); } ob_end_clean(); // fix memory problems with readfile (http://heap.tumblr.com/post/119127049/a-note-about-phps-output-buffer-and-readfile) flush(); // fix memory problems with readfile readfile($url); @ob_end_flush(); exit(); } /* file is served from my filesystem */ public function serveFileFromPath() { if (empty($_POST)) { return; } $url = APP_PATH . '/download/' . $_POST['file_name']; $mime = $_POST['mime']; $name = sanitizeFileName($_POST['name']) . '-' . uniqid() . '.' . $mime; $size = $_POST['size']; if (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== false) { // for Internet Explorer if ($mime == 'mp3') { header('Content-Type: "audio/' . $mime . '"'); } else { header('Content-Type: "video/' . $mime . '"'); } header('Content-disposition: attachment; filename="' . $name . '"'); header('Expires: 0'); if ($size !== '') { header('Content-Length: ' . $size); } header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); header("Content-Transfer-Encoding: binary"); header('Pragma: public'); } else { // not for internet Explorer if ($mime == 'mp3') { header('Content-Type: "audio/' . $mime . '"'); } else { header('Content-Type: "video/' . $mime . '"'); } header('Content-disposition: attachment; filename="' . $name . '"'); header('Expires: 0'); if ($size !== '') { header('Content-Length: ' . $size); } header("Content-Transfer-Encoding: Binary"); header('Pragma: no-cache'); } ob_end_clean(); // fix memory problems with readfile (http://heap.tumblr.com/post/119127049/a-note-about-phps-output-buffer-and-readfile) flush(); // fix memory problems with readfile readfile($url); @ob_end_flush(); exit(); } }
誰かが終わることはありませんPOSTリクエストを回避するためのソリューションを持っていますか? 問題を解決できるかどうかは、PHP以外の方法でファイルを提供するのは大丈夫です。
してくださいなし複製、私はこの質問を特定するために十分なコード、confにスニペットや写真を追加した:)
そのコードの50%を取り除くための簡単な方法は、ヘッダロケーション別名、HTTPリダイレクトとserveFileFromUrl()部分を交換することであろう。それはあなたの問題をどんな運にも修正するかもしれません。 – Calimero
タイムラインを0に設定しました。 tisは確かに修正ではありませんが、10時間のようなものを設定すると、今のような何かが失敗してもサーバーが生き残ります。スクリプトを実行すると考える時間を2倍に設定します。 – Elentriel
@Calimeroもし私がヘッダの場所だけを使うならば、ファイル(これはビデオファイルです)がブラウザで再生されます。ファイルをダウンロードします。 – hedi