Web伺服器和動態語言如何互動--CGI&FastCGI&FPM淺談,web伺服器互動--cgi
一個使用者的Request是如何經過Web伺服器(Apache,Nginx,IIS,Light)與後端的動態語言(如PHP等)進行互動並將結果返回給使用者的呢?
本文淺談個人觀點,可能有誤,歡迎拍磚,共同學習。
一. 首先明確幾個概念,以便後續說明
CGI:(Common Gateway Interface)Http伺服器與後端程式(如PHP)進行互動的中介層。
工作原理及處理方式(fork-and-execute模式):
1.當Web Server有Request到達
2.fork一個CGI進程或線程(組態管理,環境初始化)
3.執行後台指令碼
4.將結果返回Web伺服器。
5.Web伺服器將結果返回給使用者。
FastCGI:常駐型(long-live)CGI形式,經過啟用後,不會每次都要花時間去fork。
工作原理及處理方式:
1.Web Server啟動時載入FastCGI進程管理器(IIS ISAPI或Apache Module)
2.FastCGI進程管理器自身初始化,啟動多個CGI解譯器進程(可見多個php-cgi進程),並等待來自Web Server的串連
3.當有用戶端請求到達Web Server時,FastCGI進程管理器選擇並串連到一個CGI解譯器;Web Server將CGI環境變數和標準輸入發送到FastCGI子進程php-cgi。
4.FastCGI子進程完成處理後將標準輸出和錯誤資訊返回Web Server。當FastCGI子進程關閉串連時,請求便告知處理完成。子進程繼續響應來自FastCGI進程管理器分配的其他請求。
PHP-FPM:只用於PHP的PHP FastCGI 進程管理器。
PHP5.3.3以後的版本已經整合了PHP-FPM了。
php-fpm提供了更好的PHP組態管理方式,可以有效控制記憶體和進程、可以平滑重載php配置。
./configure php源碼的時候,加—enable-fpm參數可開啟PHP_FMP。
Spawn-FCGI:一個普通的FastCGI進程管理器。
二. PHP中的CGI實現:
PHP的CGI實現本質上是以Socket編程實現一個TCP或者UDP協議伺服器。當啟動時, 建立TCP/UDP協議的伺服器監聽,並接受相關請求進行處理。
CGI的生命週期為:模組初始化;SAPI初始化;請求的處理;模組關閉;SAPI關閉;
以TCP協議為例,在TCP的服務端,會執行如下操作:
1.服務端調用Socket函數建立一個TCP用的流式通訊端;
2.服務端調用bind函數將伺服器的本地地址與前面建立的通訊端綁定;
3.服務調用listen函數將新建立的通訊端作為監聽,等待用戶端發起串連,當用戶端有多個串連串連到這個通訊端時,可能需要排隊處理;
4.伺服器調用accept函數進入阻塞狀態,直到有客戶進程調用connect函數而建立起一個串連;
5.當與用戶端建立串連後,伺服器調用read_stream函數讀取客戶的請求;
6.處理完資料後,伺服器調用write函數向用戶端發送應答。
三.目前PHP的工作方式(以Apache伺服器為例,因為Apache和Php是好兄弟嘛)
1.Apache Handler方式(php作為Apache伺服器的Module)
一種改進的CGI方式,把PHP的解釋模組編成so擴充,添加到Apache的modules中。
配置方式:
1.編譯PHP時,加上如下參數:
cd php-source
./configure --prefix=/home/weiyanyan/local/php --with-apxs2=/home/weiyanyan/local/apache/bin/apxs --with-mysql
說明:—with-apxs2為apache中apxs相應目錄,將在apache根目錄下的modules下產生libphp5.so
2.在apache的設定檔http.conf中增加
LoadModule php5_module modules/libphp5.so
然後在節點下增加如下mime配置
AddType application/x-httpd-php .php
2.CGI模式
前提為不能以模組模式運行。(注釋掉:LoadModule php5_module modules/libphp5.so)
在httpd.conf增加action:
Action application/x-httpd-php /cgi-bin/php-cgi
如果在/cgi目錄找不到php-cgi,可從php的bin裡面cp一個。
【可以寫一個PHP指令碼,讓其sleep(20);運行之前看機器進程中無php-cgi進程,請求的時候,會有相應的進程產生。經測試一個php-cgi進程可以承載多個請求,具體未深究,因為這種方式已經基本沒有人用了。】
3.FastCGI模式
FastCGI模式根據進程管理器的不同可以分為:Apache內建進程管理器,php-fpm進程管理器
Apache內建進程管理器:
mod_fastcgi的安裝
#wget http://www.fastcgi.com/dist/mod_fastcgi-2.4.6.tar.gz
# tar -zxvf mod_fastcgi-2.4.6.tar.gz
# cd mod_fastcgi-2.4.6
# cp Makefile.AP2 Makefile
# vim Makefile 將Makefile中的路徑改成你的apache的安裝路徑
# make install 安裝成功
安裝成功後,會自動把mod_fastcgi.so複製到/usr/local/apache/modules目錄
首先要添加fastcgi模組到httpd.conf設定檔:
LoadModule fastcgi_module modules/mod_fastcgi.so
這種模式注釋不注釋LoadModule php5_module modules/libphp5.so這行貌似沒什麼關係,只要配置了以下模組
FastCgiServer /home/weiyanyan/local/apache/cgi-bin/php-cgi -processes 20
AddType application/x-httpd-php .php
AddHandler php-fastcgi .php
Action php-fastcgi /cgi-bin/php-cgi
就會自動走到fastcgi模式。
然後重啟apache,這個時候用 ps aux|grep php就會發現有很多php-cgi進程在運行。說明配置生效.
FPM方式
首先要添加fastcgi模組到httpd.conf設定檔:
LoadModule fastcgi_module modules/mod_fastcgi.so
這種模式注釋不注釋LoadModule php5_module modules/libphp5.so這行貌似沒什麼關係,只要配置了以下模組
FastCgiExternalServer /home/weiyanyan/local/apache/cgi-bin/php-cgi -host 127.0.0.1:9000
AddType application/x-httpd-php .php
AddHandler php-fastcgi .php
Action php-fastcgi /cgi-bin/php-cgi
其中在本機9000連接埠開啟了PHP-Fpm服務
FPM的安裝簡單介紹如下:
cd php-source
./configure --prefix=/home/weiyanyan/local/php --with-apxs2=/home/weiyanyan/local/apache/bin/apxs --with-mysql --enable-fpm
此時在Php的根目錄sbin下會有php-fpm運行程式,其設定檔在php根目錄下面的/etc/php-fpm.conf
修改完配置,在apache配置對應的連接埠啟動php-fpm即可。
[只是寫完,未檢查,回家過年…]
參考:
http://www.phppan.com/2011/05/php-cgi/
http://www.cnblogs.com/fangbo/archive/2011/12/02/2272400.html
http://blog.zyan.cc/nginx_php_v6/
http://www.bkjia.com/PHPjc/959695.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/959695.htmlTechArticleWeb伺服器和動態語言如何互動--CGIFastCGIFPM淺談,web伺服器互動--cgi 一個使用者的Request是如何經過Web伺服器(Apache,Nginx,IIS,Light)與後端的...