什麼是 FastCGI
談到 FastCGI 不能不提 CGI
fastcgi 和 CGI 二者都是公共/通用網關接口(Common Gateway Interface) ,目的是實現WEB 服務器和其它程序間的通信,簡單的理解就是實現 http 請求處理。
某種方向也可以人為 fastcgi 是 CGI 的子集。但並不是全部。
先有了 CGI 後才有了 fastcgi。基於這樣的邏輯 FastCGI 的出現是為了彌補CGI 的核心不足:
1) CGI 在處理每次的 HTTP 請求過程中都會 fork 出一個新的進程,並且反復。
反之 FastCGI 的優點
1) FastCGI 在啟動是只需產生 1 個系統進程(fork 一次)(官方喊他:Persistence 持久)
2) FastCGI 獨立於服務器架構,獨立於服務器進程
3) FastCGI 基於 Unix domain socket 或者 tcp/ip 進行通信
基於上述的論點我們在簡單實現 CGI 和 fastCGI 的 《hello world!》。
1 用 C++ 實現 CGI hello_cgi.cpp
#includeusing namespace std;int i;int main(){ i=0; cout<<"Content-type: text/html\r\n"<<endl; cout<<"CGI hello world!"<<endl; cout<<"hello world!\n"<<endl; cout<<"統計:"<<i<<""<<endl;return 1;}
編譯:
g++ -o hello hello_cgi.cpp
nginx 理論上不支持 CGI,那就用 apache 來實現 hello 的調用
具體配置參考:http://man.chinaunix.net/newsoft/ApacheManual/howto/cgi.html
把編譯好的 hello 拷貝到 apache 目錄下的 cgi-bin 文件夾下
訪問:http://127.0.0.1:8081/cgi-bin/hello
上述實現 CGI 接下來實現 FastCGI
還是一樣通過 C++ 編寫 hello_fastcgi.cpp
#include#include "fcgi_stdio.h"using namespace std;int i;int main(void){ i=0;while(FCGI_Accept() "= 0){ i++; printf("Content-type: text/html\r\n" \ "\r\n" \ "Test" \ "%s \n 統計:%d\n","Hello World",i); } return 0; }
編譯:
g++ -o hello.cgi hello_fastcgi.cpp -lfcgi -L/usr/local/lib -lfcgi
像啟動 php-fpm 一樣啟動編譯好的 hello.cgi
spawn-fcgi -a 0.0.0.0 -p 7788 -C 25 -f /你的目錄/hello.cgi
修改 nginx 配置
location ~ \.cgi$ { fastcgi_pass 127.0.0.1:7788; fastcgi_index hello.cgi; fastcgi_param SCRIPT_FILENAME /你的目錄/$fastcgi_script_name;}
重啟 nginx 訪問
http://127.0.0.1/hello.cgi
看到上面的執行結果和配置過程,應該對 cgi 和 fastcgi 有個簡單的了解過程。
重點分析下 fastcgi
按照 fastcgi 官方(http://www.fastcgi.com/drupal/node/6?q=node/15)的說法 每次的執行過程大致分為:
1 FCGI_PARAMS 從 web 服務器如 nginx 向 fastcgi 應用程序發送請求數據、環境變量 等
2 FCGI_STDIN 接送從 web 服務器發送來的數據
3 FCGI_DATA 過濾 web 服務器發送來的數據
4 FCGI_STDOUT 發送數據到 web 服務器
5 FCGI_STDERR 發送狀態到 web 服務器 如錯誤信息
6 FCGI_END_REQUEST 結束本次 http 請求
事實上在開發過程中開發者更多關心的是 FCGI_STDIN、FCGI_DATA、FCGI_STDOUT 這幾個過程,
當然如果你實在開發 fastcgi client 除外。如果基於 nginx 開發更多的數據包裝如環境變量、
GET/POST 數據的處理都委托給我 nginx 的 fastcgi 模塊。
看看前面的 hello_fastcgi.cpp當
spawn-fcgi 在啟動 hello.cgi 的時候把其載入內存,並通過 FCGI_Accept() “=0 開啟響應循環
通過 getenv 獲取核心環境變量參數, 具體參考 nginx fastcgi_params 文件 。如
getenv(“QUERY_STRING”)、getenv(“DOCUMENT_URI”)