Nginx解析PHP指令碼的過程

2021-07-26 16:18:47 字數 2690 閱讀 6408

之前專案中碰到了一些php-fpm的問題:因為**的一些介面,在特定情況下響應特別慢(1-2分鐘),遲遲不結束,導致php-fpm數量越來越多,最後到達127個後,伺服器就沒能響應正常請求了,瀏覽器一直打轉,遲遲不響應。把介面修好後,php-fpm程序的數量就穩定了,問題得以解決。這讓我對php-fpm這個程序產生了興趣。

cgi是common gateway inte***ce(公共閘道器介面)的縮寫,它有什麼用呢?我們知道瀏覽器訪問乙個含有動態資料的頁面,瀏覽器使用http協議傳送請求。資料報經過路由器和交換機,到達目標web伺服器,web伺服器收到這個請求,需要和php通訊,才能拿到含有動態資料的頁面。為什麼要通訊?因為他們語言不通(nginx等web伺服器和php語言和語法不一樣,沒法直接溝通)

那麼,要怎麼通訊呢?最早是用cgi協議來通訊。通過cgi協議,nginx能夠將http請求轉化為php可以理解的語言(uri,post資料和get的資料,http header等資料)。cgi規定了要傳哪些資料、以什麼樣的格式傳遞給後方處理。

web伺服器本身只是內容的分發者,比如請求/index.html,web伺服器就會去尋找這個檔案,然後返回給瀏覽器,這裡指的只是靜態檔案。如果是請求/index.php會怎麼樣?web伺服器知道這不是個靜態資源,需要解析後再返回給瀏覽器,於是web伺服器就啟動乙個php直譯器程序,這個直譯器實現了cgi協議,能夠完成和後端語言php的溝通,php把該返回的動態資料還給web伺服器,然後web伺服器再發給瀏覽器。

為什麼傳統的cgi工作方式會有弊端?因為每請求乙個php指令碼,web伺服器就得為乙個請求開啟乙個php直譯器(早期是php-cgi)程序來完成解析。這意味著:每來乙個請求,直譯器就得初始化php.ini並載入php擴充套件,等環境初始化完了,再解析,解析完成後程序自動結束(即fork-and-execute模式)。

所以用cgi方式的伺服器有多少連線請求就會有多少cgi子程序,子程序反覆載入是cgi效能低下的主要原因。都會當使用者請求數量非常多時,會大量擠占系統的資源如內 存,cpu時間等,造成效能低下。

fastcgi,通俗的翻譯為快速的cgi。fastcgi,顧名思義為更快的 cgi,它允許在乙個程序內處理多個請求,而不是乙個請求處理完畢就直接結束程序,web伺服器效能上有了很大的提高。

php-fpm,即專門為php打造的fastcgi process manager(php的fastcgi管理器)。nginx使用這些php-fpm程序來和php進行通訊,你可以理解把php-fpm理解為php直譯器。

和傳統的php-cgi的直譯器不同,php-fpm實現了fastcgi協議,而且還新增了不少特性。比如php-fpm能夠平滑重啟php環境配置:

實現了fastcgi協議的nginx,第一次啟動時,會啟動乙個php-fpm的master程序,該master程序初始化環境後,啟動多個worker程序(即php-fpm程序池中的php-fpm),如下圖:

當請求發來後,master程序把請求分發到程序池中的php-fpm,分發完後,就可以接下乙個請求了,避免了重複勞動(重複載入php.ini初始化環境),效率自然提公升了。當請求多的時候,master會啟動更多的php-fpm子程序,當請求少的時候,master也會停掉一些子程序。既提高了效能,也節省資源。

當然,當php-fpm設定的上限,不足以支援更高的併發請求時,nginx只能返回502錯誤了,因為沒有更多的php-fpm程序可用了。

在這種協議下,php-fpm成為了和php溝通的php直譯器。

到目前為止,我們知道了實現了fastcgi的php-fpm是如何工作的,但是nginx是怎麼啟動php-fpm程序的呢?

nginx 不僅僅是乙個 web 伺服器,也是乙個功能強大的 proxy 伺服器,除了進行 http 請求的**,也可以進行許多其他協議請求的**,包括本文與 fpm 相關的 fastcgi 協議。為了能夠使 nginx 理解 fastcgi 協議,nginx 提供了 fastcgi 模組來將 http 請求對映為對應的 fastcgi 請求。

下面是乙個nginx的配置檔案,用來把nginx中的變數,解釋為php能夠理解的變數:

下面是nginx把php請求交給fastcgi模組來處理的配置(在nginx.conf中可以查到此項配置)

在這個配置檔案中,我們新建了乙個虛擬主機,監聽在 80 埠,web 根目錄為 /home/rf/projects/wordpress。通過location配置,我們把所有.php檔案的處理,交給了fastcgi模組。之後就是fastcgi模組啟動php-fpm(實現fastcgi模組),並通過php-fpm來解釋動態請求。

下面是我總結的乙個流程圖,如果有不正確的地方,歡迎指正。

php解析的過程,php是如何經過解析的

要了解php的解析過程首先要了解cgi,fastcgi,php fpm的相關概念。cgi是什麼?cgi 通用閘道器介面 實際上是一種協議,實現cgi協議的程式我們可以稱之為cgi程式,cgi 應用程式能與瀏覽器進行互動,還可通過資料庫api 與資料庫伺服器等外部資料來源進行通訊,從資料庫伺服器中獲取...

shell指令碼nginx日誌解析入庫

bin sh 獲取nigin日誌 log path usr local nginx logs access.log cat log path while read line do 判斷該條資訊是否為我們需要 if line eleid then 替換中 和 的轉譯符 line line echo o...

Nginx與Apache解析php檔案的區別

一 apache是如何解析php檔案的 我們常說的lamp架構是linux apache mysql php,我們知道任何架構或者 離不開資料庫的支援,那麼php和apache又是如何協同工作的呢?php是apache的乙個外掛程式,必須依靠web伺服器才可以執行。當客戶端瀏覽器觸發事件 php程式...