アプリケーション開発ポータルサイト
ServerNote.NET
カテゴリー【Amazon/AWSnginx
Amazon Linux2でC/C++バイナリのFastCGIを作成しnginx経由でアクセス
POSTED BY
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.cppGitHub 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関数を使って、フォームパラメータの受け取りなどを行ってみます。

※本記事は当サイト管理人の個人的な備忘録です。本記事の参照又は付随ソースコード利用後にいかなる損害が発生しても当サイト及び管理人は一切責任を負いません。
※本記事内容の無断転載を禁じます。
【WEBMASTER/管理人】
自営業プログラマーです。お仕事ください!
ご連絡は以下アドレスまでお願いします★

【キーワード検索】