FastCGI 是 CGI 的改進版,解決了「每請求 fork 一進程」的性能瓶頸。本文對比 CGI/FastCGI 架構,展示 C++ 實現 Hello World、Nginx 配置、協議交互流程、環境變量獲取。
| 特性 | CGI | FastCGI |
| 進程模型 | 每請求 fork 新進程 | 啟動持久進程池,復用處理多請求 |
| 啟動開銷 | 每請求重複加載、初始化 | 一次啟動,常駐內存 |
| 通信方式 | stdin/stdout/環境變量 | Unix Domain Socket / TCP (IP:Port) |
| 與 Web Server 關係 | 子進程,強耦合 | 獨立進程,解耦,可遠程部署 |
| 並發處理 | 進程數 = 並發數 | 進程池 + 多路複用/多線程 |
2. C++ 實現 CGI Hello World
// hello_cgi.cpp
#include
using namespace std;
int main() {
cout << "Content-type: text/html\r\n\r\n";
cout << "CGI hello world!\n";
return 0;
}
// 編譯: g++ -o hello hello_cgi.cpp
// Apache 配置 ScriptAlias /cgi-bin/ /path/to/cgi-bin/
// 訪問: https://host/cgi-bin/hello
3. C++ 實現 FastCGI Hello World
// hello_fastcgi.cpp
#include
#include
int main() {
int count = 0;
while (FCGI_Accept() >= 0) { // 阻塞等待請求
count++;
printf("Content-type: text/html\r\n\r\n");
printf("Hello World! Request count: %d\n", count);
}
return 0;
}
// 編譯: g++ -o hello.fcgi hello_fastcgi.cpp -lfcgi
// 啟動: spawn-fcgi -a 0.0.0.0 -p 7788 -C 10 -f /path/hello.fcgi
4. Nginx 配置代理 FastCGI
location ~ \.fcgi$ {
fastcgi_pass 127.0.0.1:7788;
fastcgi_param SCRIPT_FILENAME /path/$fastcgi_script_name;
include fastcgi_params;
}
5. FastCGI 協議交互流程
- FCGI_BEGIN_REQUEST:Web Server 發送請求 ID、角色
- FCGI_PARAMS:發送環境變量(REQUEST_METHOD、QUERY_STRING、HTTP_HEADERS 等)
- FCGI_STDIN:發送 POST 數據體
- FCGI_STDOUT:應用返回響應體
- FCGI_STDERR:應用返回錯誤日誌
- FCGI_END_REQUEST:應用發送結束狀態碼
開發者關注點:FCGI_PARAMS 解析環境變量、FCGI_STDIN 讀取請求體、FCGI_STDOUT 輸出響應。Nginx fastcgi_params 已封裝常用映射。
6. 關鍵 API:FCGI_Accept / getenv
while (FCGI_Accept() >= 0) {
char* query = getenv("QUERY_STRING"); // GET 參數
char* uri = getenv("DOCUMENT_URI"); // 請求路徑
char* method = getenv("REQUEST_METHOD"); // GET/POST
char* contentLen = getenv("CONTENT_LENGTH");
// 讀取 POST 數據
if (strcmp(method, "POST") == 0) {
int len = atoi(contentLen);
char* body = malloc(len + 1);
fread(body, 1, len, stdin); // FCGI_STDIN 映射到 stdin
body[len] = '\0';
// 處理...
free(body);
}
// 輸出響應
printf("Content-type: application/json\r\n\r\n");
printf("{\"status\":\"ok\"}");
}
總結
FastCGI 通過持久進程 + Socket 通信 實現高性能 Web 應用接口。C++ 開發只需鏈接 libfcgi、循環 FCGI_Accept、解析環境變量、讀寫標準流。現代架構常用 PHP-FPM、uWSGI、Gunicorn 等進程管理器,C++ 亦可接入或自建池化框架。
- 上一篇文章: PHP XML 與 Array 互轉完整指南:四種解析方案與 DOM 生成
- 下一篇文章: C 語言 sprintf 與 sscanf 內部機制:數字與字符串雙向轉換的本質
Copyright ©
程式碼之家 All Rights Reserved