1. 程式人生 > 實用技巧 >深入理解PHP之:Nginx 與 FPM 的工作機制

深入理解PHP之:Nginx 與 FPM 的工作機制

深入理解PHP之:Nginx 與 FPM 的工作機制

網 絡上有很多關於如何配置 Nginx + FPM 的文章,但它們更多從操作的角度出發,告訴我們怎麼做,但卻沒有告訴我們為什麼要這麼做,本文從 Nginx 與 FPM 的工作機制出發,探討配置背後的原理,讓我們真正理解 Nginx 與 PHP 是如何協同工作的。

要說 Nginx 與 PHP 是如何協同工作的,首先得說 CGI (Common Gateway Interface) 和 FastCGI 這兩個協議。

CGI 是 Web Server 與後臺語言互動的協議,有了這個協議,開發者可以使用任何語言處理 Web Server 發來的請求,動態的生成內容。但 CGI 有一個致命的缺點,那就是每處理一個請求都需要 fork 一個全新的程序,隨著 Web 的興起,高併發越來越成為常態,這樣低效的方式明顯不能滿足需求。就這樣,FastCGI 誕生了,CGI 很快就退出了歷史的舞臺。FastCGI,顧名思義為更快的 CGI,它允許在一個程序內處理多個請求,而不是一個請求處理完畢就直接結束程序,效能上有了很大的提高。

至於 FPM (FastCGI Process Manager),它是 FastCGI 的實現,任何實現了 FastCGI 協議的 Web Server 都能夠與之通訊。FPM 之於標準的 FastCGI,也提供了一些增強功能,具體可以參考官方文件:PHP: FPM Installation

FPM 是一個 PHP 程序管理器,包含 master 程序和 worker 程序兩種程序:master 程序只有一個,負責監聽埠,接收來自 Web Server 的請求,而 worker 程序則一般有多個 (具體數量根據實際需要配置),每個程序內部都嵌入了一個 PHP 直譯器,是 PHP 程式碼真正執行的地方,下圖是我本機上 fpm 的程序情況,1一個 master 程序,3個 worker 程序:

ff986d4481f8f809713e98bb2b91a685_b.png

從 FPM 接收到請求,到處理完畢,其具體的流程如下:

  1. FPM 的 master 程序接收到請求

  2. master 程序根據配置指派特定的 worker 程序進行請求處理,如果沒有可用程序,返回錯誤,這也是我們配合 Nginx 遇到502錯誤比較多的原因。

  3. worker 程序處理請求,如果超時,返回504錯誤

  4. 請求處理結束,返回結果

FPM 從接收到處理請求的流程就是這樣了,那麼 Nginx 又是如何傳送請求給 fpm 的呢?這就需要從 Nginx 層面來說明了。

我 們知道,Nginx 不僅僅是一個 Web 伺服器,也是一個功能強大的 Proxy 伺服器,除了進行 http 請求的代理,也可以進行許多其他協議請求的代理,包括本文與 fpm 相關的 fastcgi 協議。為了能夠使 Nginx 理解 fastcgi 協議,Nginx 提供了 fastcgi 模組來將 http 請求對映為對應的 fastcgi 請求。

Nginx 的 fastcgi 模組提供了 fastcgi_param 指令來主要處理這些對映關係,下面 Ubuntu 下 Nginx 的一個配置檔案,其主要完成的工作是將 Nginx 中的變數翻譯成 PHP 中能夠理解的變數。

64519c5be72799e4eb8853b549f912ee_b.png除此之外,非常重要的就是 fastcgi_pass 指令了,這個指令用於指定 fpm 程序監聽的地址,Nginx 會把所有的 php 請求翻譯成 fastcgi 請求之後再發送到這個地址。下面一個簡單的可以工作的 Nginx 配置檔案:

644b6dae3878fa8caa202531971e768c_b.png在 這個配置檔案中,我們新建了一個虛擬主機,監聽在 80 埠,Web 根目錄為 /home/rf/projects/wordpress。然後我們通過 location 指令,將所有的以 .php 結尾的請求都交給 fastcgi 模組處理,從而把所有的 php 請求都交給了 fpm 處理,從而完成 Nginx 到 fpm 的閉環。

如此以來,Nginx 與 FPM 通訊的整個流程應該比較清晰了吧。

以上

2016年4月2日
北京

轉載地址 : http://zhuanlan.zhihu.com/p/20694204

轉載於:https://blog.51cto.com/stoneryan/1767493