9

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ログファイル:私の問題にとって興味深いものは何もありません

問題がいつ発生するかを示す munin グラフ: ここに画像の説明を入力

私の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 スニペット、および写真を追加しました:)

4

1 に答える 1