天天看點

【入門篇】Nginx + FastCGI 程式(C/C++) 搭建高性能web service的Demo及部署釋出

由于最近工作的需要,本人學習了一下利用高性能web server - Nginx,來釋出C/C++編寫的fastCGI程式,詳細細節如下。

1.介紹

    Nginx - 高性能web server,這個不用多說了,大家都知道。

    FastCGI程式 - 常駐型CGI程式,它是語言無關的、可伸縮架構的CGI開放擴充,其主要行為是将CGI解釋器程序保持在記憶體中并是以獲得較高的性能。

    Nginx要調用FastCGI程式,需要用到FastCGI程序管理程式(因為nginx不能直接執行外部的cgi程式,我們可使用lighttpd中的spawn-fastcgi來讓nginx可支援外部cgi運作。也有其他方法安裝nginx-fcgi來讓nginx支援cgi,這裡是使用spawn-fastcgi的方法),來達到調用FastCGI程式的目的。Nginx本身沒有內建類似的子產品,而Apache具備該功能子產品,是以不需要額外安裝FastCGI程序管理程式。

2.工作原理

    Nginx不支援對外部程式的直接調用或者解析,所有的外部程式(包括PHP)必須通過FastCGI接口來調用。FastCGI接口在Linux下是socket(這個socket可以是檔案socket,也可以是ip socket)。為了調用CGI程式,還需要一個FastCGI的wrapper(wrapper可以了解為用于啟動另一個程式的程式),這個wrapper綁定在某個固定socket上,如端口或者檔案socket。

    當Nginx将CGI請求發送給這個socket的時候,通過FastCGI接口,wrapper接收到請求,然後派生出一個新的線程,這個線程調用解釋器或者外部程式處理腳本并讀取傳回資料;接着,wrapper再将傳回的資料通過FastCGI接口,沿着固定的socket傳遞給Nginx;最後,Nginx将傳回的資料發送給用戶端。這就是Nginx+FastCGI的整個運作過程,如圖1所示。

【入門篇】Nginx + FastCGI 程式(C/C++) 搭建高性能web service的Demo及部署釋出

​圖1 Nginx+FastCGI運作過程​

    FastCGI接口方式在腳本解析伺服器(CGI應用程式伺服器)上啟動一個或者多個守護程序對動态腳本進行解析,這些程序就是FastCGI程序管理器,或者稱為FastCGI引擎。 spawn-fcgi與PHP-FPM都是FastCGI程序管理器(支援PHP和C/C++​)。​

    介紹到這裡,大家應該都對該模式有了一定的了解,下面開始進行實戰!    

3.環境部署

3.1.Nginx的安裝、部署與配置

    nginx下載下傳目錄 http://nginx.org/en/download.html

    這我們使用的是nginx-1.5.10

    [安裝]

    下載下傳以後解壓并安裝(請記得看README)

    ./configure (注意了類似checking for *** ... not found項,可能是依賴包沒有,則需要安裝依賴包)

    缺少pcre,則需要額外安裝 http://www.pcre.org/ (或者采用apt-get或yum的安裝方式)

    缺少zlib,則需要額外安裝 http://www.zlib.net/ (或者采用apt-get或yum的安裝方式)  

    缺少OpenSSL,則需要額外安裝 http://www.openssl.org (或者采用apt-get或yum的安裝方式)  

    如果需要配置安裝額外的功能子產品,可以參考這裡 http://wiki.codemongers.com/NginxChsInstall

    make

    make install (預設安裝到/usr/local/nginx)

    [配置和管理]     

    1)執行選項

        -c </path/to/config> 為 Nginx 指定一個配置檔案,來代替預設的。不輸入則使用預設的配置檔案。

        -t 不運作,而僅僅測試配置檔案。nginx 将檢查配置檔案的文法的正确性,并嘗試打開配置檔案中所引用到的檔案。

        -v 顯示 nginx 的版本。

        -V 顯示 nginx 的版本,編譯器版本和配置參數。

    2)檢查配置檔案

        sudo ./nginx -t

        nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok

        nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful

     3)啟動 - 預設和特殊

        /usr/local/nginx/sbin/nginx (預設啟動方式)

        /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf (指定配置檔案啟動)

    4)檢視nginx程序号(master是主程序)

        ps -ef | grep nginx 

    5)重新加載配置檔案

        sudo kill -HUP [nginx主程序号]

        通過系統的信号控制 Nginx

        可以使用信号系統來控制主程序。預設,nginx 将其主程序的 pid 寫入到 /usr/local/nginx/logs/nginx.pid 檔案中。通過傳遞參數        給 ./configure 或使用 pid 指令,來改變該檔案的位置。

        主程序可以處理以下的信号:

        指令

說明 備注

        TERM, INT 快速關閉

        QUIT 從容關閉

        HUP 重載配置

用新的配置開始新的工作程序    從容關閉舊的工作程序

        USR1 重新打開日志檔案

        USR2 平滑更新可執行程式

        WINCH 從容關閉工作程序

    6)預設目錄結構

        主目錄:/usr/local/nginx/

        配置目錄:/usr/local/nginx/conf/

        root目錄:/usr/local/nginx/html/

        可執行檔案路徑:/usr/local/nginx/sbin/

3.2.spawn_fastcgi的安裝、部署與配置

    spawn_fastcgi  https://github.com/lighttpd/spawn-fcgi 

    這裡使用的是1.6.3的版本 https://github.com/lighttpd/spawn-fcgi/releases/tag/v1.6.3

    下載下傳以後解壓并安裝(請記得看README)

    如果沒有configure,請先執行./autogen.sh,生成configure

    ./configure

    make

    編譯好以後,将可執行檔案移動到nginx的sbin目錄下

    cp ./src/spawn-fcgi /usr/local/nginx/sbin/ (cp到nginx的安裝目錄下)

3.3.fastcgi庫的安裝(庫絕對不是必須的,覺得技術好的大牛可以自己寫)

    庫位址 http://www.fastcgi.com/dist/fcgi.tar.gz

    下載下傳以後,解壓并安裝 (預設安裝)

    ./configure

    make install

4.Demo和web釋出

4.1.Demo程式

    [CGI程式]    

#include <fcgi_stdio.h>  

#include <stdlib.h>  

int main() {  

    int count = 0;  

    while (FCGI_Accept() >= 0) {  

        printf("Content-type: text/html\r\n"  

                "\r\n"  

                ""  

                "FastCGI Hello!"  

                "Request number %d running on host%s "  

                "Process ID: %d\n", ++count, getenv("SERVER_NAME"), getpid());  

    }  

    return 0;  

}  

    [編譯]

    g++ demo.cc -o demo  -lfcgi​  

    直接運作可執行檔案,看看能否正常運作。如果出現缺少庫libfcgi.so.0,則自己需要手動把/usr/local/lib/libfcgi.so.0庫建立一個連結到/usr/lib/目錄下:ln -s /usr/local/libfcgi.so.0 /usr/lib/(或者把so的庫路徑添加到/etc/ld.so.conf,并執行ldconfig更新一下)

4.2.Web釋出

    1)将CGI可執行程式移動到nginx的安裝目錄下 /usr/local/nginx/cgibin (檔案夾不存在則自己建立) 

    2)啟動spawn-fcgi管理程序,并綁定server IP和端口(不要跟nginx的監聽端口重合)

     /usr/local/nginx/sbin/spawn-fcgi -a 127.0.0.1 -p 8088 -f /usr/local/nginx/cgibin/demo

    檢視一下9002端口是否已成功:netstat -na | grep 8088

​   

    3)更改nginx.conf配置檔案,讓nginx轉發請求

    在http節點的子節點-"server節"點中下添加配置

    location ~ \.cgi$ {

        fastcgi_pass 127.0.0.1:8088;

        fastcgi_index index.cgi;

        fastcgi_param SCRIPT_FILENAME fcgi$fastcgi_script_name;

        include fastcgi_params;

    }

    4)重新開機nginx或者重新加載配置檔案

    重新加載配置檔案

    sudo kill -HUP [pid]

    或者

    重新開機nginx    

    killall nginx

​    ./nginx

    5)打開浏覽器通路一下吧

    http://localhost/demo.cgi

    搞定收工,心裡又小小的激動了一把!

allenrlin

2014/2/18

    參考文獻與資料

    [1]Nginx+FastCGI運作原理​  http://book.51cto.com/art/201202/314840.htm

    ​[2]Nginx下配置FastCGI ​ http://www.cppblog.com/woaidongmao/archive/2011/06/21/149090.html

    [3]nginx+fastcgi+c/c++搭建高性能Web架構​  ​http://blog.csdn.net/marising/article/details/3932938​

    [4]什麼是CGI、FastCGI、PHP-CGI、PHP-FPM、Spawn-FCGI  ​http://www.mike.org.cn/articles/what-is-cgi-fastcgi-php-fpm-spawn-fcgi/​