Web服務器和動態語言如何交互--CGI&FastCGI&FPM淺談

一個用戶的Request是如何通過Web服務器(Apache,Nginx,IIS,Light)與後端的動態語言(如PHP等)進行交互並將結果返回給用戶的呢?php

本文淺談我的觀點,可能有誤,歡迎拍磚,共同窗習。html

 

一. 首先明確幾個概念,以便後續說明mysql

CGI:(Common Gateway Interface)Http服務器與後端程序(如PHP)進行交互的中間層。nginx

工做原理及處理方式(fork-and-execute模式):sql

1.當Web Server有Request到達apache

2.fork一個CGI進程或線程(配置管理,環境初始化)編程

3.執行後臺腳本vim

4.將結果返回Web服務器。後端

5.Web服務器將結果返回給用戶。服務器

image

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進程管理器分配的其餘請求。

image

 

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函數向客戶端發送應答。

TCP上客戶-服務器事務的時序

 

三.目前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

而後在<IfModule mime_module>節點下增長以下mime配置

AddType application/x-httpd-php .php
image

 

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一個。

image

【能夠寫一個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這行貌似沒什麼關係,只要配置瞭如下模塊

<IfModule fastcgi_module>
   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
</IfModule>

就會自動走到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這行貌似沒什麼關係,只要配置瞭如下模塊

<IfModule fastcgi_module>
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
</IfModule>

其中在本機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/

相關文章
相關標籤/搜索