PerlのFastCGIアプリケーション。 パート1

しばらく前、私はオンラインオークションのエンジンを書くよう依頼されました。 エンジンを通常の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テクノロジーに精通しています。



次の部分-アプリケーションのデモでは、スクリプトをサーバーに変えます。



オリジナル記事



All Articles