なぜ、Windowsでphp-cgiが自動で終了してしまうのか?(Windows+Nginx+php-cgi.exe)
ご利用のブラウザは、JavaScript が無効 となっていませんか?
このサイトでは、コンテンツの一部が非表示 、あるいは、コメント、お問い合わせの投稿ができない 、検索ができない ことがあります。
Windowsで(L)AMP(Nginx,MySQL,PHP)インストールからWordPressを動かすまで で、Windows に (Apacheのかわり)Nginx、M ySQL、P HP をインストールし、Wordpressを動かすまでを簡単に解説してみました。
確かに 先の記事のとおりで、問題なく動作しますが、しばらく使用していると、php-cgiのプロセスが無くなっています。自動的に終了してしまっています。
これが毎回同じタイミングで終了しているので、ちょっと調べてみました。
ここで使用するPHPは、VisualStudio 2008 (VC++)で作成されたバイナリファイルになります。
そのため、使用するWindowsに 少なくとも VC9 のランタイムライブラリは必要になります。
各ランタイムライブラリは、以下からダウンロードし、インストールしておきましょう。
Nginx,MySQL は、不要です。
なぜ、Windowsでphp-cgiが自動で終了してしまうのか?
原因と対処
話は、前後しますが、細かい理由はともかく、原因とその対処について、まず、簡単に解説してみます。
なぜ、Windowsでphp-cgiが自動で終了してしまうのか?
色々と調べてみると、結論は、
これは、何かphpのコードに問題があって、php-cgiがクラッシュしたのかと思いきや、単純に、PHP_FCGI_MAX_REQUESTS で設定されている要求回数分を処理しきったので、自動的に終了しているにすぎないことがわかりました。
ちょっと勘違いしていたのは、
PHP_FCGI_MAX_REQUESTS のデフォルト値が、500 であることです。何も設定しない場合は、0 (無制限) だとばかり思っていました。
何のことはない、何も設定しなければ500回なので、 おおよそ 100ページビュー ぐらいでしょうか、それぐらいで php-cgiのプロセスが終了していたことになります。
これだと、実際に終了したいたタイミングに合致しますから、間違いなさそうです。
これの対処は、PHP_FCGI_MAX_REQUESTS を 0 (無制限) にしてしまうか
php-cgi が自動的に終了したら、php-cgi を再起動すれば良いでしょう。
この2つの対処について、以下に簡単なバッチファイルを作成してみましょう。
ここでは、phpのインストール先を、D:\WEB\php
としています。
つまり、D:\WEB\php\php-cgi.exe
が存在するものとします。
いずれも簡単なバッチです。適当なファイル名(拡張子 .bat)で保存、実行するだけで、利用できると思います。
終了する場合は、バッチファイルが起動しているDOS窓で、Ctrl + C
で終了できます。
理由(おまけ)
話は、前後しましたが、この問題の本質(理由)は、php-cgiがWindows版ではspawn管理しないことにあります。
そもそも php-cgiは、2つの環境変数を使用できます。
PHP_FCGI_MAX_REQUESTS :
先にも解説したように php-cgiが処理する要求数 になります。ここで設定された回数の要求を処理したら、自動で終了します。
デフォルト : 500 回です。
PHP_FCGI_CHILDREN :
php-cgiが管理する子プロセス数 になります。この値が0より大きい値の場合は、その数だけ子プロセスを生成します。
この場合、先のPHP_FCGI_MAX_REQUESTS は、子プロセスに対して有効となります。子プロセスが要求回数を満たし、自動的に終了しても、親プロセスが再起動してくれます。
デフォルト : 0 です。子プロセスを管理しません。
ただ、このPHP_FCGI_CHILDREN は、Windows版では使用できない ようです。
Bug #49859 PHP_FCGI_CHILDREN not work でPHP 5.3 にてバグ報告されていますが、
Status : Not a bug とされていて、仕様のようです。
ただ、コメントを見ると、Windowsだけなぜできないようになっているのか?確かに変な感じもしますが、変更する気はなさそうなので、使えないのでしょうね。
先の問題もそもそもの原因は、PHP_FCGI_CHILDREN が使えないことにあります。
PHP_FCGI_MAX_REQUESTS 、PHP_FCGI_CHILDREN を正しく使えていないのは、知識不足によるところですが、本来のバッチイメージでは、以下のようになるはずです。
@ ECHO OFF
ECHO Starting PHP FastCGI...
set PATH=D:\WEB\php;% PATH %
set PHP_FCGI_MAX_REQUESTS=500
set PHP_FCGI_CHILDREN=5
php-cgi.exe -b 127.0.0.1:9000
PHP_FCGI_MAX_REQUESTS については、正しく動作していますから、PHP_FCGI_CHILDREN が正しく動作すれば、上記の設定で プロセスのサイクル化ができるはずなんですね。
ただ、残念ながら、これは動作しません。LinuxのBシェルなら以下のように起動すれば、きれいに phpプロセスのサイクル化ができます。
$ PHP_FCGI_MAX_REQUESTS=500 PHP_FCGI_CHILDREN= 5 php- cgi - b 127. 0. 0. 1: 9000
別のシェルでプロセスを確認すれば、以下のように5つの子プロセスが起動していることが確認できると思います。
$ ps aux| grep php
root 7605 0.3 0.6 58224 6912 pts/1 S+ 13:01 0:00 php-cgi -b 127.0.0.1:9000
root 7606 0.0 0.2 58224 2520 pts/1 S+ 13:01 0:00 php-cgi -b 127.0.0.1:9000
root 7607 0.0 0.2 58224 2520 pts/1 S+ 13:01 0:00 php-cgi -b 127.0.0.1:9000
root 7608 0.0 0.2 58224 2520 pts/1 S+ 13:01 0:00 php-cgi -b 127.0.0.1:9000
root 7609 0.0 0.2 58224 2520 pts/1 S+ 13:01 0:00 php-cgi -b 127.0.0.1:9000
root 7610 0.0 0.2 58224 2520 pts/1 S+ 13:01 0:00 php-cgi -b 127.0.0.1:9000
root 7612 0.0 0.0 2988 820 pts/2 S+ 13:01 0:00 grep php
一番先頭のphp-cgiが親プロセスになります。以降の5つが子プロセスです。
また、<?php phpinfo(); ?>
で環境変数を確認することもできます。
いかがだったでしょうか?
随分、以前に調べたことですが、備忘録がてら記事にしました。
また、どうやったら、Windowsで php-cgi をシンプルに再起動ができるか?・・・なんて考えていて、
とりあえず、Windowsの RestartOnCrash というフリーのツールを使っていましたが、単純にバッチ内でループすれば何も問題ないなぁ と はたと気づいて記事にしました。
Nginxのデバッグ環境をWindowsで構築されている方には、ちょっとだけ参考になるかもしれません。
ご利用のブラウザは、広告ブロック(AdBlockなど) が適用 となっていませんか?
このサイトでは、コンテンツの一部が非表示 、あるいは、コメント、お問い合わせの投稿ができない 、検索ができない ことがあります。
関連記事 :
コメントを投稿 :