2023-10-25
FastCGIとは、CGIプログラム自体をデーモンプロセスとして常時起動させておきアクセスを早くしようという仕組みで、FastCGI.comにてヘッダファイル、リンクライブラリ、起動プログラムが提供されている。
Apacheやnginxといったウェブサーバーは、特定のリクエストに対し、上記のように裏で常時起動しているFastCGIプロセスに投げて、結果を受け取りそのまま出力する。このための設定はnginxには元々存在し、Apacheにおいてはmod_fcgiを組み込むことで可能となる。
今回はAmazon Linux2環境下で、FastCGIソースをC/C++で書きコンパイル、常時起動、nginxで設定しアクセスする。なお、起動プログラムはFastCGI.com純正のcgi-fcgiコマンドがあるので、lighttpdの付属品であるspawn-fcgiは不要です。
FastCGIソフトウェアのインストール
ヘッダファイル、リンクライブラリ、起動プログラムをインストールする。
パッケージからインストールする場合
sudo -s amazon-linux-extras install epel yum install fcgi-devel
この場合、/usr/{bin,lib,include}にインストールされる。
ソースコードからインストールする場合
sudo -s cd /usr/local/src # fcgi-devel # ココからソースアーカイブを探す https://fastcgi-archives.github.io/ wget https://github.com/FastCGI-Archives/FastCGI.com/raw/master/original_snapshot/fcgi-2.4.1-SNAP-0910052249.tar.gz tar xvfzp fcgi-2.4.1-SNAP-0910052249.tar.gz cd fcgi-2.4.1-SNAP-0910052249/ ./configure make make install
この場合、/usr/local/{bin,lib,include}にインストールされる。
nginxのインストール
Amazon Linux2ではyumに無くamazon-linux-extras nginx1となる。
sudo amazon-linux-extras install nginx1
FastCGIプログラムを書く
Hello world文字列とアクセス数を返すC/C++サンプル
C/C++ | fcgi_test.cpp | GitHub Source |
#include <stdint.h> #include <sys/types.h> #include <unistd.h> #include "fcgi_config.h" #include "fcgi_stdio.h" int main (void) { uint32_t access_counter = 0; while (FCGI_Accept() >= 0) { FCGI_printf("Content-type: text/plain\r\n" "\r\n" "Hello World! Access Counter : %ld\n", ++access_counter); } return 0; }
コンパイル・リンク
Amazon Linux2では、/usr/localに-I/-Lパスを指定しなくても元々通してくれている模様。
g++ -o test.fcgi fcgi_test.cpp -lfcgi
実行バイナリファイルtest.fcgiが出来上がる。場所は/home/ec2-user以下にできたものとする。
FastCGIデーモンプロセスとして起動
ローカルのnginxから接続するわけなので、UNIXドメインソケットを使う。これをTCPソケットにしてしまってはFastCGIを使う意味が無い。cgi-fcgiコマンドのUNIXドメイン例が見つからなかったがmanに記載あり。第1引数をTCP/IP:PORT形式からソケットファイルパス指定に変えればよい。
ps aux | grep fcgi # すでに立ち上がっていないか確認,あったらkillしておく cgi-fcgi -connect /home/ec2-user/test.sock /home/ec2-user/test.fcgi Content-type: text/plain Hello World! Access Counter : 1
と、確認出力してくれる。プログラムは終わってしまった訳ではなく、
ps aux | grep fcgi ec2-user 28674 0.0 0.0 17524 1856 pts/0 S 22:58 0:00 /home/ec2-user/test.fcgi
しっかり常駐している事が確認できる。
ソケットファイルのパーミッションを誰でも書き込み可に変更
chmod a+w /home/ec2-user/test.sock
こうしておかないとnginxプロセスがwww-data等別ユーザ権限だとPermission Deniedになる。
あとはnginxの設定でこのFastCGIにUNIXドメイン指定でつなげてあげれば良い。
nginxの設定と起動
nginx.confのserverブロックにlocationを差し込む。
sudo -s cd /etc cp -Rp nginx nginx.default # バックアップ cd nginx vi nginx.conf server { ...抜粋... location ~ .cgi$ { root /home/ec2-user/www; fastcgi_pass unix:/home/ec2-user/test.sock; fastcgi_index index.cgi; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include /etc/nginx/fastcgi_params; } ...抜粋... }
.cgiへのアクセスを常駐中のtest.fcgiへ流す設定。
fastcgi_pass unix:/home/ec2-user/test.sock;
でUNIXドメインソケットファイルを指定するのが最大のポイント。
起動、自動起動設定
起動
systemctl stop nginx # 立ち上がっていたら停止 systemctl start nginx # 起動 systemctl status nginx # 確認 ps aux | grep nginx # 確認 tail /var/log/syslog # 確認
自動起動設定
systemctl enable nginx # 設定 systemctl status nginx # 確認
FastCGI接続実行テスト
いよいよnginx経由でテスト。nginxは80番で立ち上がっているので、telnetで手動アクセス。
telnet localhost 80 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. GET /fast.cgi HTTP/1.0 HTTP/1.1 200 OK Server: nginx/1.18.0 Date: Fri, 23 Oct 2020 14:29:20 GMT Content-Type: text/plain Connection: close Hello World! Access Counter : 2 Connection closed by foreign host.
fast.cgiと、最後を.cgiとしてリクエストしているので、nginx.confのlocationが発火し、無事さきほどのプログラムにアクセス、カウンターが加算されて返されているのが確認できた。常駐プログラムなので、カウンタ変数がリセットされていないのがポイント。
次回あたりで、FCGI_で始まる他のFastCGI C/C++ API関数を使って、フォームパラメータの受け取りなどを行ってみます。
※本記事内容の無断転載を禁じます。
ご連絡は以下アドレスまでお願いします★
Windowsのデスクトップ画面をそのまま配信するための下準備
WindowsでGPUの状態を確認するには(ASUS系監視ソフトの自動起動を停止する)
CORESERVER v1プランからさくらインターネットスタンダートプランへ引っ越しメモ
さくらインターネットでPython MecabをCGIから使う
さくらインターネットのPHPでAnalytics-G4 APIを使う
インクルードパスの調べ方
【Git】特定ファイルを除外する.gitignore
【Ubuntu/Debian】NVIDIA関係のドライバを自動アップデートさせない
【Python】Spacyを使用して文章から出発地と目的地を抜き出す
【Windows10】リモートデスクトップ間のコピー&ペーストができなくなった場合の対処法
【Apache】サーバーに同時接続可能なクライアント数を調整する
GitLabにHTTPS経由でリポジトリをクローン&読み書きを行う
Windows版Google Driveが使用中と言われアンインストールできない場合
【Linux】iconv/libiconvをソースコードからインストール
【C/C++】小数点以下の切り捨て・切り上げ・四捨五入
Windows11+WSL2でUbuntuを使う【2】ブリッジ接続+固定IPの設定
【PHP】Mail/mimeDecodeを使ってメールの中身を解析(準備編)
Googleファミリーリンクで子供の端末の現在地がエラーで取得できない場合