1. 程式人生 > >php的執行原理、cgi對比fastcgi以及php-cgi和php-fpm之間的聯絡區別

php的執行原理、cgi對比fastcgi以及php-cgi和php-fpm之間的聯絡區別

最近專案中本地測試環境遇到了windows環境下的nginx使用file_get_contents/curl訪問php檔案導致的阻塞問題,一直在找解決的方案,這個問題研究了三天終於找到了解決方案,特別因為這個我也對php的執行原理產生了興趣,所以這裡對此進行一定程度的記錄,可能會有錯漏的地方,歡迎指正。

要了解php的執行原理,首先要了解下面幾個概念:

CGI:

CGI的英文是(COMMON GATEWAY INTERFACE)公共閘道器介面,它的作用就是幫助伺服器與語言通訊,這裡就是nginx和php進行通訊,因為nginx和php的語言不通,因此需要一個溝通轉換的過程,而CGI就是這個溝通的協議。

nginx伺服器在接受到瀏覽器傳遞過來的資料後,如果請求的是靜態的頁面或者圖片等無需動態處理的則會直接根據請求的url找到其位置然後返回給瀏覽器,這裡無需php參與,但是如果是一個動態的頁面請求,這個時候nginx就必須與php通訊,這個時候就會需要用到cgi協議,將請求資料轉換成php能理解的資訊,然後php根據這些資訊返回的資訊也要通過cgi協議轉換成nginx可以理解的資訊,最後nginx接到這些資訊再返回給瀏覽器。

fast-cgi:

傳統的cgi協議在每次連線請求時,會開啟一個程序進行處理,處理完畢會關閉該程序,因此下次連線,又要再次開啟一個程序進行處理,因此有多少個連線就有多少個cgi程序,這也就是為什麼傳統的cgi會顯得緩慢的原因,因此過多的程序會消耗資源和記憶體。

而fast-cgi則是一個程序可以處理多個請求,和上面的cgi協議完全不一樣,cgi是一個程序只能處理一個請求,這樣就會導致大量的cgi程式,因此會給伺服器帶來負擔。

php-cgi:

php-cgi是php提供給web serve也就是http前端伺服器的cgi協議介面程式,當每次接到http前端伺服器的請求都會開啟一個php-cgi程序進行處理,而且開啟的php-cgi的過程中會先要過載配置,資料結構以及初始化執行環境,如果更新了php配置,那麼就需要重啟php-cgi才能生效,例如phpstudy就是這種情況。

php-fpm:

php-fpm是php提供給web serve也就是http前端伺服器的fastcgi協議介面程式,它不會像php-cgi一樣每次連線都會重新開啟一個程序,處理完請求又關閉這個程序,而是允許一個程序對多個連線進行處理,而不會立即關閉這個程序,而是會接著處理下一個連線。它可以說是php-cgi的一個管理程式,是對php-cgi的改進。

php-fpm會開啟多個php-cgi程式,並且php-fpm常駐記憶體,每次web serve伺服器傳送連線過來的時候,php-fpm將連線資訊分配給下面其中的一個子程式php-cgi進行處理,處理完畢這個php-cgi並不會關閉,而是繼續等待下一個連線,這也是fast-cgi加速的原理,但是由於php-fpm是多程序的,而一個php-cgi基本消耗7-25M記憶體,因此如果連線過多就會導致記憶體消耗過大,引發一些問題,例如nginx裡的502錯誤。

同時php-fpm還附帶一些其他的功能:

例如平滑過渡配置更改,普通的php-cgi在每次更改配置後,需要重新啟動才能初始化新的配置,而php-fpm是不需要,php-fpm分將新的連線傳送給新的子程式php-cgi,這個時候載入的是新的配置,而原先正在執行的php-cgi還是使用的原先的配置,等到這個連線後下一次連線的時候會使用新的配置初始化,這就是平滑過渡。

可能上面文字敘述很難理解,下面用圖形來簡要的說明瀏覽器請求web伺服器的過程、cgi以及fastcgi,以及php-cgi和php-fpm之間的區別和聯絡:

上面是使用php-fpm的動態頁面的過程,下面補充沒有普通cgi協議的情況;

這裡的web server可以是nginx,也可以是IIS和apache等http伺服器,也可以成為網站伺服器或者前端伺服器。