しばらく前、私はオンラインオークションのエンジンを書くよう依頼されました。 エンジンを通常のCGIのようにするか、もっと面白いことをするかを選択しました。 エンジンの開発にFastCGIテクノロジーを適用することにしました。
FastCGIは、Webサーバーとアプリケーション間の相互作用を提供するクライアントサーバープロトコルです。 FastCGIは、CGIプロトコルをさらに発展させたものです。
違いは何ですか?
通常のCGIアプリケーションの場合、Webサーバーとアプリケーション間の対話はSTDINとSTDOUTを介して行われます。 FastCGIを使用する場合、クライアントとサーバー間の対話は、UnixソケットまたはTCP / IPを介して行われます。
これら2つのオプションのうち、より興味深いのはTCP / IP通信です。 このオプションには、2つの重要な利点があります。
1)FastCGIアプリケーションは、Webサーバーと同じサーバーだけでなく、他のサーバーでも起動できます。 このようなサーバーとFastCGIアプリケーションはいくつでも実行でき、これにより、システムを拡張するためのほぼ無限の範囲が提供されます。 システムは負荷への対処を停止しましたか? 大丈夫-必要な数のサーバーを完全に再構築せずに簡単に追加できます。 既存のシステムとの最大の干渉は、Webサーバーの構成に新しいIPのリストを含む行を追加することのみです。
2)FastCGIアプリケーションは、デーモンとして実装できます。 それ自体がサーバーである可能性があります。 通常のCGIアプリケーションは、新しいリクエストごとにWebサーバーによって起動されます。 アプリケーションの起動には時間の大部分がかかります。多くの場合、起動には、実行する有用な作業よりも時間がかかります。 FastCGIアプリケーションは常に実行されており、起動に時間を浪費する必要はなく、有用な作業を行うだけで済みます。
あなたはこれらの魅力にお金を払わなければなりません。 まず、FastCGIアプリケーションの作成は、CGIアプリケーションの作成よりも多少複雑です。 次に、Webサーバーには追加の構成が必要であり、場合によっては交換が必要です。
Webサーバーから始めましょう。
この場合、Webサーバーは非常に小さな役割を果たし、仮想ホストの解決も、スクリプトの実行も、静的なレンダリングも行いません。 彼のすべての作業は、ブラウザーからFastCGIアプリケーションに要求を転送することになります。
Nginxはこのタスクに適しています。
アプリケーションで動作するようにnginxを構成するには、nginxの構成に次の構成を追加する必要があります。
#パスがfcgi-binディレクトリで始まるリクエスト、
#は処理のためにFastCGIアプリケーションに渡されます。
場所/ fcgi-bin / {
#リクエストの送信先
#この場合、FastCGIアプリケーションは同じコンピューター上にあり、ポート9000でリッスンします
fastcgi_pass localhost:9000;
}
(nginxの設定の詳細については、
ソースを参照してください)
nginxを起動します。 仮想ホストtest.hostがnginxで構成されている場合、アドレス
test.host/fcgi-binへのブラウザー内のリクエストは、nginxによってFastCGIアプリケーションに送信されます。 アプリケーション自体はまだありませんが、次のようなものがブラウザに表示されます。
「お探しのページは一時的に利用できません。 後でもう一度やり直してください。 „
これは正常です。 そうであるはずです。
それでは、FastCGIアプリケーションの作成に移りましょう。
FastCGIプロトコルは、
FCGIモジュールとしてPerlに実装されて
います。 CPANには、CGI :: Fastなど、FastCGIで作業できる他のモジュールがありますが、それらはすべてFCGIのアドオンであることに注意してください。 「基本的な」FCGIモジュールを直接使用します。
#!/ usr / bin / perl
#物を整理する
厳格な使用;
警告を使用します。
#このモジュールはFastCGIプロトコルを実装しています。
FCGIを使用します。
#ソケットを開く
#スクリプトはポート9000でリッスンします
#接続キューの長さ(バックログ)-5個
my $ socket = FCGI :: OpenSocket( ":9000"、5);
#聞き始める
my $ request = FCGI :: Request(\ * STDIN、\ * STDOUT、\ * STDERR、\%ENV、$ socket);
私の$カウント= 1;
#無限ループ
#受信したリクエストごとに、サイクルの1つの「革命」が実行されます。
while($ request-> Accept()> = 0){
#ループ内で、すべての有用な作業が行われます
print "Content-Type:text / plain \ r \ n \ r \ n";
印刷$カウント++;
};
いくつかのポイントをさらに詳しく調べてみましょう。
OpenSocket関数はソケットを開き、ポート9000をソケットにバインドしますが、このポートをnginx構成で指定したことを忘れないでください。 まだ忘れないでください-1024未満のポートはルートにならなければ開くことができません。
この関数のbacklogパラメーターは、以前の接続が提供されている間にキューで待機する接続の数を設定します。 正直なところ、このオプションがどのように機能するのか理解できませんでした。 理論的には、キューがいっぱいの場合、新しい接続をドロップする必要があります。 しかし、目に見える効果のこのパラメーターに変更はありません。その数は指定しません-それにもかかわらず、すべての接続が整列され、単一の接続はリセットされません。 私はおそらくどこかで何かを見逃していますが、これはスクリプトのパフォーマンスに影響を与えないようです。
Request関数は要求ハンドラーを作成します。 ハンドラーは標準記述子を「インターセプト」し、それらをWebサーバーにバインドします。 これは、特に、スクリプト内のリクエスト中にエラーが発生した場合、それに関するメッセージはコンソールに表示されず、Webサーバーに送信されることを意味します。 nginxログでこのメッセージを探す必要があります。 一般的に、この点で通常のCGIスクリプトの動作は似ていますが、唯一の違いはCGIアプリケーションのログが近くにあり、FastCGIアプリケーションのログは完全に異なるサーバーにあるということです。
「Content-Type」ヘッダーの出力を無視しないでください(まあ、少なくともいくつかのヘッダー)。 これがないと、nginxはブラウザへの出力を拒否します。 一般に、この動作は、通常のCGIアプリケーションを使用する場合のWebサーバーの動作にも似ています。
さて、スクリプトを作成して実行します。 どこでも構文エラーを犯していない場合、スクリプトはサイレントに実行され、何も表示されず、コンソールもリリースされません-これは正常な動作です。 これで、スクリプトはポート9000をリッスンし、Webサーバーがポート9000に接続するまで待機する必要があります。
ブラウザを起動してアドレス
test.host/fcgi-binを開きます
。nginxの設定を確認したときにすでに開いていることを覚えていますか? ただし、今回は、ページにアクセスできないというメッセージの代わりに、単純な数字が表示されるはずです。1. F5ボタンを押します。 図が増加するはずです。
おめでとうございます! FastCGIアプリケーションを作成して起動しました。 このアプリケーションはまだ非常に原始的であり、これまでのところ実際のFastCGIサーバーではありませんが、一般に、すでにFastCGIテクノロジーに精通しています。
次の部分-アプリケーションのデモでは、スクリプトをサーバーに変えます。
(
オリジナル記事 )