CGI與FastCGI

先說一個重要結論

  • nginx+PHP-FPM在高併發狀況下可能會達到Apache+mod_php5的5~10倍,如今nginx+PHP-FPM使用的人愈來愈多。

CGI

  • CGI的英文是(COMMON GATEWAY INTERFACE)公共網關接口,服務器並不能直接運行 php,asp這樣的文件,它的做用就是幫助服務器與語言通訊,這裏就是nginx和php進行通訊,由於nginx和php的語言不通,所以須要一個溝通轉換的過程,而CGI就是這個溝通的協議。
  • nginx服務器在接受到瀏覽器傳遞過來的數據後,若是請求的是靜態的頁面或者圖片等無需動態處理的則會直接根據請求的url找到其位置而後返回給瀏覽器,這裏無需php參與,可是若是是一個動態的頁面請求,這個時候nginx就必須與php通訊,這個時候就會須要用到cgi協議,將請求數據轉換成php能理解的信息,而後php根據這些信息返回的信息也要經過cgi協議轉換成nginx能夠理解的信息,最後nginx接到這些信息再返回給瀏覽器。

fast-cgi

  • 傳統的cgi協議在每次鏈接請求時,會開啓一個進程進行處理,處理完畢會關閉該進程,所以下次鏈接,又要再次開啓一個進程進行處理,所以有多少個鏈接就有多少個cgi進程,這也就是爲何傳統的cgi會顯得緩慢的緣由,所以過多的進程會消耗資源和內存。php

  • 而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仍是使用的原先的配置,等到這個鏈接後下一次鏈接的時候會使用新的配置初始化,這就是平滑過渡。

示意圖

FastCGI的整個工做流程

  • Web Server啓動時載入FastCGI進程管理器(IIS ISAPI或Apache Module)
  • 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在此便退出了。
相關文章
相關標籤/搜索