本文從Nginx與FPM的工作機(jī)制出發(fā),探討配置背后的原理扒腕,讓我們真正理解Nginx與PHP是如何協(xié)同工作的寞钥。要說Nginx與PHP是如何協(xié)同工作的蚁廓,首先得說CGI (Common Gateway Interface)和FastCGI這兩個協(xié)議雷激。
CGI是Web Server與后臺語言交互的協(xié)議替蔬,有了這個協(xié)議,開發(fā)者可以使用任何語言處理Web Server發(fā)來的請求屎暇,動態(tài)的生成內(nèi)容承桥。但CGI有一個致命的缺點(diǎn),那就是每處理一個請求都需要fork一個全新的進(jìn)程根悼,隨著Web的興起凶异,高并發(fā)越來越成為常態(tài),這樣低效的方式明顯不能滿足需求挤巡。就這樣剩彬,F(xiàn)astCGI誕生了,CGI很快就退出了歷史的舞臺矿卑。FastCGI喉恋,顧名思義為更快的CGI,它允許在一個進(jìn)程內(nèi)處理多個請求母廷,而不是一個請求處理完畢就直接結(jié)束進(jìn)程轻黑,性能上有了很大的提高。
至于FPM (FastCGI Process Manager)琴昆,它是FastCGI的實現(xiàn)苔悦,任何實現(xiàn)了FastCGI協(xié)議的Web Server都能夠與之通信。FPM之于標(biāo)準(zhǔn)的FastCGI椎咧,也提供了一些增強(qiáng)功能,具體可以參考官方文檔:PHP: FPM Installation把介。
FPM是一個PHP進(jìn)程管理器勤讽,包含master進(jìn)程和worker進(jìn)程兩種進(jìn)程:master進(jìn)程只有一個,負(fù)責(zé)監(jiān)聽端口拗踢,接收來自Web
Server的請求脚牍,而worker進(jìn)程則一般有多個(具體數(shù)量根據(jù)實際需要配置),每個進(jìn)程內(nèi)部都嵌入了一個PHP解釋器巢墅,是PHP代碼真正執(zhí)行的地方诸狭,下圖是我本機(jī)上fpm的進(jìn)程情況,1一個master進(jìn)程君纫,3個worker進(jìn)程:
從FPM接收到請求驯遇,到處理完畢,其具體的流程如下:
1.FPM的master進(jìn)程接收到請求
2.master進(jìn)程根據(jù)配置指派特定的worker進(jìn)程進(jìn)行請求處理蓄髓,如果沒有可用進(jìn)程叉庐,返回錯誤,這也是我們配合Nginx遇到502錯誤比較多的原因会喝。
3.worker進(jìn)程處理請求陡叠,如果超時玩郊,返回504錯誤
4.請求處理結(jié)束,返回結(jié)果
FPM從接收到處理請求的流程就是這樣了枉阵,那么Nginx又是如何發(fā)送請求給fpm的呢译红?這就需要從Nginx層面來說明了。
我們知道兴溜,Nginx不僅僅是一個Web服務(wù)器侦厚,也是一個功能強(qiáng)大的Proxy服務(wù)器,除了進(jìn)行http請求的代理昵慌,也可以進(jìn)行許多其他協(xié)議請求的代理假夺,包括本文與fpm相關(guān)的fastcgi協(xié)議。為了能夠使Nginx理解fastcgi協(xié)議斋攀,Nginx提供了fastcgi模塊來將http請求映射為對應(yīng)的fastcgi請求已卷。
Nginx的fastcgi模塊提供了fastcgi_param指令來主要處理這些映射關(guān)系,下面Ubuntu下Nginx的一個配置文件淳蔼,其主要完成的工作是將Nginx中的變量翻譯成PHP中能夠理解的變量侧蘸。
除此之外,非常重要的就是fastcgi_pass指令了鹉梨,這個指令用于指定fpm進(jìn)程監(jiān)聽的地址讳癌,Nginx會把所有的php請求翻譯成fastcgi請求之后再發(fā)送到這個地址。下面一個簡單的可以工作的Nginx配置文件:
在這個配置文件中存皂,我們新建了一個虛擬主機(jī)晌坤,監(jiān)聽在80端口,Web根目錄為/home/rf/projects/wordpress旦袋。然后我們通過location指令骤菠,將所有的以.php結(jié)尾的請求都交給fastcgi模塊處理,從而把所有的php請求都交給了fpm處理疤孕,從而完成Nginx到fpm的閉環(huán)商乎。
如此以來,Nginx與FPM通信的整個流程應(yīng)該比較清晰了吧祭阀。