PHPのpopenで開いたfgetsを使ったプロセス読み込みに時間制限をつけたい。
私は次のコードを持っています:
$handle = popen("tail -F -n 30 /tmp/pushlog.txt 2>&1", "r");
while(!feof($handle)) {
$buffer = fgets($handle);
echo "data: ".$buffer."\n";
@ob_flush();
flush();
}
pclose($handle);
私は成功せずに試しました:
set_time_limit(60);
ignore_user_abort(false);
プロセスは次のとおりです。
- ブラウザーは、HTML5 サーバー側イベント形式で応答を待機する GET 要求を送信します。
- リクエストは AWS Load Balancer によって受信され、EC2 インスタンスに転送されます。
- 答えはファイルの最後の 30 行です
- ブラウザは 30 メッセージで受信し、接続は維持されます。
- tail コマンドが新しい行を送信した場合、それが返されます。それ以外の場合、fgets は、tail コマンドから新しい行が返されるまで未定義の時間待機します。
- 60 秒間ネットワークが非アクティブになった後 (60 秒間新しい行がない)、AWS Load Balancer はブラウザへの接続を閉じます。EC2 インスタンスへの接続が閉じられていません。
- ブラウザーは接続が閉じられたことを検出し、新しい接続を開きます。プロセスはステップ 1 に戻ります。
この手順で説明されているように、AWS ロード バランサーと EC2 インスタンス間の接続は決して閉じられません。数時間または数日後に、何百ものテール プロセスと httpd プロセスが実行され、サーバーが応答しなくなります。
もちろん、これは AWS Load Balancer のバグのようですが、プロセスを開始して Amazon の注意を引き、修正を待つ必要はありません。
私の一時的な解決策は、サーバーが不安定になる前にプロセスを強制終了するために sudo kill tail を実行することです。
fgets が終了するのを待って PHP が「ブロック」されているため、PHP はスクリプトを停止しないと思います。
AWS Load Balancer の時間制限が編集可能であることは知っていますが、デフォルト値のままにしておきたいです。制限を高くしても問題は解決しません。
質問を時間制限/タイムアウトでLinuxでプロセスを実行する方法に変更する必要があるかどうかわかりません。
PHP 5.5.22 / Apache 2.4 / Linux カーネル 3.14.35-28.38.amzn1.x86_64