一、什麼是CGI
- cgi是服務器端運行的一個進程,cgi使用輸入輸出與客戶端進行交互(下圖所示)
- 使用場景:例如牛客網等平臺中的在線編程工具,網頁客戶端將數據當做輸入傳遞給後端的cgi程序,cgi程序處理完成之後將結果作爲輸出返回給客戶端
- cgi與server進程的區別:cgi使用輸入輸出與客戶端進行交互,但是server使用的是http等協議與客戶端進行交互
二、FastCGI
- CGI工作原理:每當客戶請求CGI的時候,WEB服務器就請求操作系統生成一個新的CGI解釋器進程,CGI的一個進程則處理完一個請求後退出,下一個請求來時再創建新進程。當然,這樣在訪問量很少沒有併發的情況也行。可是當訪問量增大,併發存在,這種方式就不適合了。於是就有了fastcgi
- FastCGI工作原理:FastCGI像是一個常駐型的CGI,它可以一直執行着,只要激活後,不會每次都要花費時間去fork一次(這是CGI最爲人詬病的fork-and-execute 模式)
- 總結起來就是:
- cgi是一個請求(一個客戶端)對應一個進程,一個請求來時就創建一個cgi進程,請求結束後銷燬該cgi進程
- FasiCGI就是在後端申請一個進程池,請求來了之後從進程池中取進程,而不用每次創建銷燬
三、Nginx中的FastCGI模塊
- Nginx有一個fast_cgi模塊,其能與任何兼容FastCGI協議的服務器通信
- 其相關指令在前面的文章介紹過了,指令可以參閱:https://blog.csdn.net/qq_41453285/article/details/106321984
四、運行FastCGI程序的環境搭建
- 需要準備兩樣東西:
- ①cgi開發庫:其提供相關cgi程序的接口,可以用來開發cgi程序
- ②spawn-fcgi:cgi程序編寫好之後,需要用spawn-fcgi來運行cgi程序
①cgi開發庫的編譯安裝
- 第一步:下載fcgi庫,網址爲:ftp://ftp.slackware.com/.2/gentoo/distfiles/fcgi-2.4.0.tar.gz,下載完成之後解壓
tar zxf fcgi.tar.gz
- 第二步:進入目錄,進行配置
cd fcgi-2.4.1-SNAP-0311112127 ./configure
- 第三步:輸入make編譯,第一次編譯的時候會出錯,錯誤解決辦法見第四步
make
- 第四步:上面的錯誤意義爲:在fcgio.cpp文件中找打不EOF的定義。EOF定義在<stdio.h>頭文件中,因此只需要找到fcgio.cpp文件,在其內部加上<stdio.h>頭文件即可。fcgio.cpp位置在fcgi根目錄的libfcgi目錄下
vim ./libfcgi/fcgio.cpp
- 第五步:修改完成之後,接着輸入make進行編譯,這一次編譯成功
make
- 第六步:輸入下面的命令將庫安裝到系統中
sudo make install
- 默認安裝完成之後,就可以在下面的目錄中查看到對應的文件了
- fcgi的頭文件被存放到:/usr/local/include
- fcgi的動態庫文件被存放到:/usr/local/lib/
- 第七步:輸入下面的命令,重新加載一下動態庫
sudo /sbin/ldconfig
②spawn-fcgi的編譯安裝
- 第一步:下載spawn-fcgi庫,網址爲:https://codeload.github.com/lighttpd/spawn-fcgi/tar.gz/spawn-fcgi-1.6.4,下載完成之後解壓
tar zxf spawn-fcgi-1.6.4.tar.gz
- 第二步:進入目錄,進行配置
cd ./configure
- 第三步:輸入make編譯
make
- 第四步:編譯完成之後在src/目錄下會產生一個spawn-fcgi程序,將這個編譯好的spawn-fcgi程序拷貝到Nginx服務器安裝目錄的sbin/目錄下(例如我的Nginx安裝在/usr/local/nginx/目錄下)
sudo cp ./src/spawn-fcgi /usr/local/nginx/sbin/
- 備註:在此處我們沒有輸入“make install”把spawn-fcgi程序進行安裝,感興趣的讀者也可以自己安裝,但是此處我們直接把該程序拷貝到Nginx對應的目錄下使用就可以了
五、編程演示案例
- 讓Nginx運行FastCGI程序的工作原理大致爲:
- 第一步:先編寫一個FastCGI程序(例如名爲demo.c),然後將其編譯爲一個可執行程序(例如編譯名爲demo)
- 第二步:使用spwanfcgi程序運行你這個FastCGI程序demo
- 第三步:編寫Nginx配置文件,在配置文件的location模塊中使用FasiCGI指令聲明你這個FastCGI程序
- 第四步:客戶端通過URI訪問Nginx配置文件中對應FastCGI程序的location的URI,與CGI程序進行交互
第一步:
- 編寫一個FastCGI程序,名爲demo.c,代碼如下
#include <stdio.h> #include <fcgi_stdio.h> int main() { while(FCGI_Accept() >= 0) { printf("Content-type: text/html\r\n"); printf("\r\n"); printf("<title>Fast-CGI Hello! </title>"); printf("<h1>dongshao</h1>"); printf("Thank You cgi\n"); } }
- 編譯上面的demo.c,編譯的時候需要加上-lfcgi選項
gcc -o demo demo.c -lfcgi
第二步:
- 編寫一個Nginx配置文件,存放在/usr/local/nginx/conf/myconf/目錄下,名爲my_fast_cgi.conf
- 配置文件說明如下:
- Nginx的運行端口爲9000
- fastcgi_pass指令:FastCGI程序運行的地址
- fastcgi_index指令: 如果請求的Fastcgi_index URI是以/結束的, 該指令設置的文件會被附加到URI的後面並保存在變量$fastcig_script_name中
- fastcgi_param指令:設置傳遞到FastCGI程序的參數和參數的值
- include指令:我們的配置文件使用到了FastCGI模塊,那麼就需要在內部引入Nginx給我們默認提供的fastcgi配置文件,這個配置文件名爲fastcgi_params,存放在/usr/local/nginx/conf/目錄下(注意路徑,下面我給出的是相對路徑)
worker_processes 4; events { worker_connections 1024; } http { server { listen 9000; # 只要URI以.cgi結尾,都會訪問到這個location location ~ \.cgi { fastcgi_pass 192.168.0.103:9001; #如果客戶端輸入的URI是以/結尾的,那麼默認訪問/index.cgi程序 fastcgi_index index.cgi; fastcgi_param SCRIPT_FILENAME cgi$fastcgi_script_name; # 引入Nginx提供的fastcgi配置文件,注意路徑 include ../fastcgi_params; } } }
- 使用上面那個配置文件運行Nginx
sudo /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/myconf/my_fast_cgi.conf
第三步:
- 使用上面我們介紹的spwanfcgi程序運行這個cgi程序
- -a:表明這個cgi程序運行時的IP
- -p:表明這個cgi程序運行時的端口
- -f:表明運行的cgi程序(路徑別錯了)
sudo /usr/local/nginx/sbin/spawn-fcgi -a 192.168.0.103 -p 9001 -f ~/code/nginx/demo
第四步:
- 通過瀏覽器訪問Nginx配置的cgi程序,URI爲192.168.0.103:9000/demo.cgi