Apache サーバー、php アプリに大きな問題があります。
サーバーは、php で実行されている非常にトラフィックの多い Web サイトにサービスを提供しています。
24 時間または 48 時間ごとに apache がハングし、Web サイトに再びアクセスできるように再起動する必要があります。apache が許可されているプロセス/サーバーの最大数 (私の場合は 16000) に達し、他のプロセスがすべてアクティブであるため、他のプロセスを解放できないため、再起動する必要があります。
このサーバーでホストされている Web サイトは、最後にファイルを提供する php アプリです。ダウンロード サーバーとしましょう。
ファイルは、POST 要求を送信するフォームを介してブラウザーによって要求されます。
問題は、この POST リクエストが終了しないように見えることです (サーバー ステータスの 16000 プロセスのほぼすべてが POST リクエストであることがわかります)。
提供されるファイルは大きなファイル (10M から 2G) であり、php の readfile 関数を使用して提供します (href リンクを提供したくないので、フォーム POST 要求を使用して、ユーザーがファイルの場所を確認できないようにします)。ファイルは私のファイルシステムにあります)。
php readfile を使用する関数は、最後に exit() を使用しても終了しないようです (以下のコード スニペットを参照)。
私はここで、私のphpコードによって引き起こされる終わりのないPOSTリクエストを回避する方法を求めています. ファイルを提供する POST の方法を維持したい。
最初に私のconf:
- Ubuntu サーバー 14.04
- mpm プリフォークを使用した Apache 2.4
- php 5.5.9 (mod php)
- ハードウェア: 128G RAM
私の 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 スニペット、および写真を追加しました:)