這篇文章主要介紹的內容是關於CGI、FastCGI和PHP-FPM關係圖解 ,有著一定的參考價值,現在分享給大家,有需要的朋友可以參考一下
目錄
基礎
Module方式
CGI
FastCGI介紹
PHP-FPM介紹
總結
參考資料
在搭建 LAMP/LNMP 伺服器時,會經常遇到 PHP-FPM、FastCGI和CGI 這幾個概念。如果對它們一知半解,很難搭建出高效能的伺服器。接下來我們就以圖形方式,解釋這些概念之間的關係。
基礎
在整個網站架構中,Web Server(如Apache)只是內容的分發者。舉個栗子,如果用戶端請求的是 index.html,那麼Web Server會去檔案系統中找到這個檔案,發送給瀏覽器,這裡分發的是待用資料。
如果請求的是 index.php,根據設定檔,Web Server知道這個不是靜態檔案,需要去找 PHP 解析器來處理,那麼他會把這個請求簡單處理,然後交給PHP解析器。
當Web Server收到 index.php 這個請求後,會啟動對應的 CGI 程式,這裡就是PHP的解析器。接下來PHP解析器會解析php.ini檔案,初始化執行環境,然後處理請求,再以規定CGI規定的格式返回處理後的結果,退出進程,Web server再把結果返回給瀏覽器。這就是一個完整的動態PHP Web訪問流程,接下來再引出這些概念,就好理解多了,
CGI:是 Web Server 與 Web Application 之間資料交換的一種協議。
FastCGI:同 CGI,是一種通訊協定,但比 CGI 在效率上做了一些最佳化。同樣,SCGI 協議與 FastCGI 類似。
PHP-CGI:是 PHP (Web Application)對 Web Server 提供的 CGI 協議的介面程式。
PHP-FPM:是 PHP(Web Application)對 Web Server 提供的 FastCGI 協議的介面程式,額外還提供了相對智能一些任務管理。
WEB 中,
Module方式
在瞭解 CGI 之前,我們先瞭解一下Web server 傳遞資料的另外一種方法:PHP Module載入方式。以 Apache 為例,在PHP Module方式中,是不是在 Apache 的設定檔 httpd.conf 中加上這樣幾句:
# 加入以下2句LoadModule php5_module D:/php/php5apache2_2.dllAddType application/x-httpd-php .php# 修改如下內容<IfModule dir_module> DirectoryIndex index.php index.html</IfModule>
上面是 Windows 下安裝php和apache環境後手動設定,在linux下源碼安裝大致是這樣配置的:
# ./configure --with-mysql=/usr/local --with-apache=/usr/local/apache --enable-track-vars
所以,這種方式,他們的共同本質都是用 LoadModule 來載入 php5_module,就是把php作為apache的一個子模組來運行。當通過web訪問php檔案時,apache就會調用php5_module來解析php代碼。
那麼php5_module是怎麼來將資料傳給php解析器來解析php代碼的呢?答案是通過sapi。
我們再來看一張圖,詳細的說說apache 與 php 與 sapi的關係:
從上面圖中,我們看出了sapi就是這樣的一個中間過程,SAPI提供了一個和外部通訊的介面,有點類似於socket,使得PHP可以和其他應用進行互動資料(apache,nginx等)。php預設提供了很多種SAPI,常見的提供給apache和nginx的php5_module、CGI、FastCGI,給IIS的ISAPI,以及Shell的CLI。
所以,以上的apache調用php執行的過程如下:
apache -> httpd -> php5_module -> sapi -> php
好了。apache與php通過php5_module的方式就搞清楚了吧!
這種模式將php模組安裝到apache中,所以每一次apache結束請求,都會產生一條進程,這個進程就完整的包括php的各種運算計算等操作。
在中,我們很清晰的可以看到,apache每接收一個請求,都會產生一個進程來串連php通過sapi來完成請求,可想而知,如果一旦使用者過多,並發數過多,伺服器就會承受不住了。
而且,把mod_php編進apache時,出問題時很難定位是php的問題還是apache的問題。
CGI
CGI(Common Gateway Interface)全稱是“通用閘道介面”,WEB 伺服器與PHP應用進行“交談”的一種工具,其程式須運行在網路伺服器上。CGI可以用任何一種語言編寫,只要這種語言具有標準輸入、輸出和環境變數。如php、perl、tcl等。
WEB伺服器會傳哪些資料給PHP解析器呢?URL、查詢字串、POST資料、HTTP header都會有。所以,CGI就是規定要傳哪些資料,以什麼樣的格式傳遞給後方處理這個請求的協議。仔細想想,你在PHP代碼中使用的使用者從哪裡來的。
也就是說,CGI就是專門用來和 網頁伺服器打交道的。web伺服器收到使用者請求,就會把請求提交給cgi程式(如php-cgi),cgi程式根據請求提交的參數作應處理(解析php),然後輸出標準的html語句,返回給web服伺服器,WEB伺服器再返回給用戶端,這就是普通cgi的工作原理。
CGI的好處就是完全獨立於任何伺服器,僅僅是做為中間分子。提供介面給apache和php。他們通過cgi搭線來完成資料傳遞。這樣做的好處了盡量減少2個的關聯,使他們2變得更獨立。
但是CGI有個蛋疼的地方,就是每一次web請求都會有啟動和退出過程,也就是最為人詬病的fork-and-execute模式,這樣一在大規模並發下,就死翹翹了。
FastCGI介紹
FastCGI簡單介紹
從根本上來說,FastCGI是用來提高CGI程式效能的。類似於CGI,FastCGI也可以說是一種協議。
FastCGI像是一個常駐(long-live)型的CGI,它可以一直執行著,只要啟用後,不會每次都要花費時間去fork一次。它還支援分布式的運算, 即 FastCGI 程式可以在網站伺服器以外的主機上執行,並且接受來自其它網站伺服器來的請求。
FastCGI是語言無關的、可伸縮架構的CGI開放擴充,其主要行為是將CGI解譯器進程保持在記憶體中,並因此獲得較高的效能。眾所周知,CGI解譯器的反覆載入是CGI效能低下的主要原因,如果CGI解譯器保持在記憶體中,並接受FastCGI進程管理器調度,則可以提供良好的效能、伸縮性、Fail- Over特性等等。
FastCGI的工作原理
FastCGI介面方式採用C/S結構,可以將HTTP伺服器和指令碼解析伺服器分開,同時在指令碼解析伺服器上啟動一個或者多個指令碼解析守護進程。當HTTP伺服器每次遇到動態程式時,可以將其直接交付給FastCGI進程來執行,然後將得到的結果返回給瀏覽器。這種方式可以讓HTTP伺服器專一地處理靜態請求,或者將動態指令碼伺服器的結果返回給用戶端,這在很大程度上提高了整個應用系統的效能。
Web Server啟動時載入FastCGI進程管理器(Apache Module或IIS ISAPI等)
FastCGI進程管理器自身初始化,啟動多個CGI解譯器進程(可建多個php-cgi),並等待來自Web Server的串連。
當用戶端請求到達Web Server時,FastCGI進程管理器選擇並串連到一個CGI解譯器。Web server將CGI環境變數和標準輸入發送到FastCGI子進程php-cgi。
FastCGI子進程完成處理後,將標準輸出和錯誤資訊從同一串連返回Web Server。當FastCGI子進程關閉串連時,請求便告處理完成。FastCGI子進程接著等待,並處理來自FastCGI進程管理器(運行在Web Server中)的下一個串連。 在CGI模式中,php-cgi在此便退出了。
FastCGI與CGI特點:
對於CGI來說,每一個Web請求PHP都必須重新解析php.ini、重新載入全部擴充,並重新初始化全部資料結構。而使用FastCGI,所有這些都只在進程啟動時發生一次。一個額外的好處是,持續資料庫連接(Persistent database connection)可以工作。
由於FastCGI是多進程,所以比CGI多線程消耗更多的伺服器記憶體,php-cgi解譯器每進程消耗7至25兆記憶體,將這個數字乘以50或100就是很大的記憶體數。
PHP-FPM介紹
要瞭解PHP-FPM,就得先說說PHP-CGI。
PHP-CGI就是PHP實現的內建的FastCGI管理器。 雖然是php官方出品,但是這丫的卻一點也不給力,效能太差,而且也很麻煩不人性化,主要體現在:
php-cgi變更php.ini配置後,需重啟php-cgi才能讓新的php-ini生效,不可以平滑重啟。
直接殺死php-cgi進程,php就不能運行了。
上面2個問題,一直讓很多人病垢了很久,所以很多人一直還是在用 Module 方式。 直到 2004年一個叫 Andrei Nigmatulin的屌絲髮明了PHP-FPM ,這神器的出現就徹底打破了這種局面,這是一個PHP專用的 fastcgi 管理器,它很爽的克服了上面2個問題,而且,還表現在其他方面更表現強勁。
也就是說,PHP-FPM 是對於 FastCGI 協議的具體實現,他負責管理一個進程池,來處理來自Web伺服器的請求。目前,PHP5.3版本之後,PHP-FPM是內建於PHP的。
因為PHP-CGI只是個CGI程式,他自己本身只能解析請求,返回結果,不會進程管理。所以就出現了一些能夠調度 php-cgi 進程的程式,比如說由lighthttpd分離出來的spawn-fcgi。同樣,PHP-FPM也是用於調度管理PHP解析器php-cgi的管理程式。
PHP-FPM通過產生新的子進程可以實現php.ini修改後的平滑重啟。
總結
最後,我們來總結一下,這些技術經過不斷的升級,可以解決什麼問題(不然也不會升級嘛)。
所以,如果要搭建一個高效能的PHP WEB伺服器,目前最佳的方式是Apache/Nginx + FastCGI + PHP-FPM(+PHP-CGI)方式了,不要再使用 Module載入或者 CGI 方式啦:)
本文章圖片用Visio製作,源檔案:php-fpm
原文地址:https://www.awaimai.com/371.html
相關推薦:
PHP7核心剖析1之CGI與FastCGI
CGI、FastCGI 和 PHP_FPM到底有什麼關係?