PHP的五大運行模式php
1)CGI( Common Gateway Interface):即通用網關接口,java
2)FastCGI( Long-Live CGI):即常駐型通用網關接口nginx
3)CLI( Command Line Interface):即命令行運行接口c++
4)Web模塊模式(Apache等Web服務器運行的模式) web
5)ISAPI(Internet Server Application Program Interface)apache
1.1 CGI是一種讓客戶端(web瀏覽器)與Web服務器(nginx等)程序進行通訊(數據傳輸)的協議。編程
1)用來規範web服務器傳輸到php解釋器中的數據類型以及數據格式,包括URL、查詢字符串、POST數據、HTTP header等,也就是爲了保證web server傳遞過來的數據是標準格式的。瀏覽器
2)CGI能夠用任何一種具備標準輸入、輸出和環境變量的語言編寫,如php、perl、tcl等。不一樣類型語言寫的程序只要符合cgi標準,就能做爲一個cgi程序與web服務器交互,早期的cgi大多都是c或c++編寫的。tomcat
3)通常說的CGI指的是用各類語言編寫的能實現該功能的程序。安全
1)每次當web server收到index.php這種類型的動態請求後,會啓動對應的CGI程序(PHP的解析器);
2)PHP解析器會解析php.ini配置文件,初始化運行環境,而後處理請求,處理完成後將數據按照CGI規定的格式返回給web server而後退出進程;
3)最後web server再把結果返回給瀏覽器。
1.3 fpm進程管理器是什麼?
進程管理器,顧名思義就是管理進程的一個「進程」;
什麼意思呢?當咱們接到一個請求時,webserver須要和php進行通訊;
通訊時會成一個主進程,咱們把它理解爲一個工廠,主進程下會生成子進程去作具體的運算,咱們把它理解爲工人;
也就是說,工廠的做用是調度,是給工人提供工做的一個平臺,工人的做用是去作工做。
1)高併發時的性能較差:
CGI程序的每一次web請求都會有啓動和退出過程,也就是最爲人詬病的fork-and-execute模式(每次HTTP服務器遇到動態請求時都須要從新啓動腳本解析器來解析php.ini,從新載入所有DLL擴展並重初始化所有數據結構,而後把結果返回給HTTP服務器),很明顯,這樣的接口方式會致使php的性能不好,在處理高併發訪問時,幾乎是不可用的。
2)傳統的CGI接口方式安全性較差
3)CGI對php.ini的配置很敏感,在開發和調試的時候至關方便
CGI已是比較老的模式了,這幾年都不多用了。 CGI爲每一次請求增長一個進程,效率很低,因此基本已經不在生產部署時採用。但因爲CGI對php配置的敏感性,一般被用在開發和調試階段。
經過CGI程序的工做原理能夠看出:CGI程序性能較差,安全性較低,爲了解決這些問題產生了FastCGI。
php爲例,我將一次動態請求相關的概念大體都簡單解釋一遍。
cgi
:它是一種協議。經過cgi協議,web server能夠將動態請求和相關參數發送給專門處理動態內容的應用程序。fastcgi
:也是一種協議,只不過是cgi的優化版。cgi的性能較爛,fastcgi則在其基礎上進行了改進。php-cgi
:fastcgi是一種協議,而php-cgi實現了這種協議。不過這種實現比較爛。它是單進程的,一個進程處理一個請求,處理結束後進程就銷燬。php-fmp
:是對php-cgi的改進版,它直接管理多個php-cgi進程/線程。也就是說,php-fpm是php-cgi的進程管理器所以它也算是fastcgi協議的實現。在必定程度上講,php-fpm與php的關係,和tomcat對java的關係是相似的。cgi進程/線程
:在php上,就是php-cgi進程/線程。專門用於接收web server的動態請求,調用並初始化zend虛擬機。cgi腳本
:被執行的php源代碼文件。zend虛擬機
:對php文件作詞法分析、語法分析、編譯成opcode,並執行。最後關閉zend虛擬機。cgi進程/線程和zend虛擬機的關係
:cgi進程調用並初始化zend虛擬機的各類環境。以php-fpm爲例,web server從轉發動態請求到結束的過程大體以下:
而每一個php-cgi進程的做用大體包括:(有些功能分類錯誤,請無視,知道大體功能就夠了)
注意,儘管php-fpm的全稱爲PHP FastCGI Process Manager,但嚴格地講,php-fpm不是fastcgi的進程管理器,而是php fastcgi即php-cgi的進程管理器。fastcgi只是一種協議,不是進程。就像http協議同樣,apache對它的實現是httpd,nginx對它的實現就叫nginx。
再次說明,cgi和fastcgi是一種協議。各類支持和WEB交互的編程語言對cgi/fastcgi協議都作了各自的實現(固然,任何一種語言都能寫cgi腳本),而php上的php-cgi和php-fpm正是php對fastcgi協議的實現。
使用CGI模式時
使用CGI模式時,當動態請求到達,httpd臨時啓動一個cgi解釋器,並經過cgi協議轉發要運行的內容。當cgi腳本運行結束後,將結果返回給httpd,而後cgi解釋器進程自我銷燬。當多個動態請求到達時,將前後啓動多個cgi解釋器。所以,這種方法效率極低。
在註釋掉php5_module的LoadModule相關行後,使用action指令指定要使用cgi運行的類型。但注意,action指令是mod_action提供的,因此必須已經加載該模塊。
例如:指定MIME類型爲image/gif的請求使用images.cgi運行。顯然,images.cgi腳本你必須先寫好。
Action image/gif /cgi-bin/images.cgi
還能夠經過添加handler來複合文件類型,再使用某個cgi腳本去運行這個handler中的任意類型。
AddHandler my-file-type .xyz Action my-file-type "/cgi-bin/program.cgi"
對於php來講,則可使用安裝php時bin目錄下提供的php-cgi程序做爲cgi程序。
[root@xuexi php]# ls /usr/local/php/bin/ pear peardev pecl phar phar.phar php php-cgi php-config phpize # 複製到apache默認的cgi-bin目錄下,方便管理 [root@xuexi php]# cp /usr/local/php/bin/php-cgi /usr/local/apache/cgi-bin/ # 在httpd.conf中添加如下行 Action application/x-httpd-php /usr/local/php/bin/cgi-bin/php-cgi
在編譯php時,將php5_module模塊編譯到apache中,例如在編譯php時在./configure配置中加上"--with-apxs2=/usr/local/apache/bin/apxs"。
這種交互模式下,httpd在啓動時加載並激活php_module。也就是說,php-cgi常駐在httpd進程內部。當動態請求到達時,httpd不用再生成cgi解釋器,而是直接將動態請求轉發給它內部php-cgi。
配置實用這種交互模式很是簡單,只需使用LoadModule加載php_module,再添加對應的MIME處理器便可。
LoadModule php5_module modules/libphp5.so # 在mime模塊中添加對應的類型 <IfModule mime_module> AddType application/x-httpd-php .php AddType applicaiton/x-httpd-php-source .phps </IfModule>
前面說了,php-fpm是php-cgi的進程管理器。這種交互方式其實是讓php-cgi以獨立於httpd的方式存在,目前基本使用php-fpm的方式管理php-cgi進程。也就是說,這種模式下,php-cgi和httpd已經分離了,它們的分離意味着請求的動靜分離變爲可能:httpd和php-fpm分別運行在不一樣服務器上。動靜分離後,壓力也分散到各自的服務器上。
要讓php-fpm以這種方式運行,須要在編譯的./configure配置選項中添加"--enable-fpm"選項。固然,還得啓動php-fpm服務。例如:
service php-fpm start
這樣php-cgi進程就開放着端口(默認9000)等待httpd轉發動態請求。要讓httpd可以轉發請求到php-cgi上,須要在httpd.conf中關閉正向代理,並設置fastcgi協議代理參數。例如,轉發到192.168.100.54主機上的php-fpm。
# 加載代理模塊 LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so # 添加MIME類型 AddType application/x-httpd-php .php AddType application/x-httpd-php-source .phps # 在須要轉發的虛擬主機中配置轉發代理 ProxyRequests off ProxyPassMatch ^/(.*\.php)$ fcgi://192.168.100.54:9000/usr/local/apache/htdocs/$1
隨着技術的不斷升級,單純的Apache加php模塊的方式已再也不主流,而是替換爲Apache加php_cgi,以及後來的php_fcgi和nginx加php-fpm的方法,能夠看下圖
PHP-CLI是PHP Command Line Interface的簡稱,如同它名字的意思,就是PHP在命令行運行的接口,區別於在Web服務器上運行的PHP環境(PHP-CGI,ISAPI等)。 也就是說,PHP不單能夠寫前臺網頁,它還能夠用來寫後臺的程序。 PHP的CLI Shell腳本適用於全部的PHP優點,使建立要麼支持腳本或系統甚至與GUI應用程序的服務端,在Windows和Linux下都是支持PHP-CLI模式的。
【優勢】
1)使用多進程,子進程結束之後,內核會負責回收資源;
2)使用多進程,子進程異常退出不會致使整個進程Thread退出,父進程還有機會重建流程;
3)一個常駐主進程,只負責任務分發,邏輯更清楚。
咱們在Linux下常用"php –m"查找PHP安裝了那些擴展就是PHP命令行運行模式;有興趣的同窗能夠輸入"php –h"去深刻研究該運行模式。