Nginx與PHP工作原理

Nginx的工作原理


1.Nginx的模塊與工作原理

Nginx由內(nèi)核和模塊組成爽待,其中鉴象,內(nèi)核的設(shè)計非常微小和簡潔抑胎,完成的工作也非常簡單梨撞,僅僅通過查找配置文件將客戶端請求映射到一個location block(location是Nginx配置中的一個指令雹洗,用于URL匹配),而在這個location中所配置的每個指令將會啟動不同的模塊去完成相應(yīng)的工作卧波。


例圖

Nginx的模塊從結(jié)構(gòu)上分為核心模塊时肿、基礎(chǔ)模塊和第三方模塊:

核心模塊:HTTP模塊、EVENT模塊和MAIL模塊

基礎(chǔ)模塊:HTTP Access模塊港粱、HTTP FastCGI模塊螃成、HTTP Proxy模塊和HTTP Rewrite模塊旦签,

第三方模塊:HTTP Upstream Request Hash模塊、Notice模塊和HTTP Access Key模塊寸宏。

用戶根據(jù)自己的需要開發(fā)的模塊都屬于第三方模塊宁炫。正是有了這么多模塊的支撐,Nginx的功能才會如此強大氮凝。

Nginx的模塊從功能上分為如下三類羔巢。

Handlers(處理器模塊)。此類模塊直接處理請求罩阵,并進行輸出內(nèi)容和修改headers信息等操作竿秆。Handlers處理器模塊一般只能有一個。

Filters (過濾器模塊)稿壁。此類模塊主要對其他處理器模塊輸出的內(nèi)容進行修改操作幽钢,最后由Nginx輸出。

Proxies (代理類模塊)傅是。此類模塊是Nginx的HTTP Upstream之類的模塊匪燕,這些模塊主要與后端一些服務(wù)比如FastCGI等進行交互,實現(xiàn)服務(wù)代理和負載均衡等功能喧笔。

下圖展示了Nginx模塊常規(guī)的HTTP請求和響應(yīng)的過程帽驯。


Nginx工作流程

Nginx本身做的工作實際很少,當(dāng)它接到一個HTTP請求時溃斋,它僅僅是通過查找配置文件將此次請求映射到一個location block 界拦,因此location中所配置的各個指令則會啟動不同的模塊去完成工作,因此模塊可以看做Nginx真正的勞動工作者梗劫。通常一個location中的指令會涉及一個handler模塊和多個filter模塊(當(dāng)然享甸,多個location可以復(fù)用同一個模塊)。handler模塊負責(zé)處理請求梳侨,完成響應(yīng)內(nèi)容的生成蛉威,而filter模塊對響應(yīng)內(nèi)容進行處理。

Nginx的模塊直接被編譯進Nginx走哺,因此屬于靜態(tài)編譯方式蚯嫌。啟動Nginx后,Nginx的模塊被自動加載丙躏,不像Apache择示,首先將模塊編譯為一個so文件,然后在配置文件中指定是否進行加載晒旅。在解析配置文件時栅盲,Nginx的每個模塊都有可能去處理某個請求,但是同一個處理請求只能由一個模塊來完成废恋。

2.Nginx的進程模型

在工作方式上谈秫,Nginx分為單工作進程和多工作進程兩種模式扒寄。在單工作進程模式下,除主進程外拟烫,還有一個工作進程该编,工作進程是單線程的;在多工作進程模式下硕淑,每個工作進程包含多個線程课竣。Nginx默認為單工作進程模式。

Nginx在啟動后喜颁,會有一個master進程和多個worker進程稠氮。

master進程

主要用來管理worker進程,包含:接收來自外界的信號半开,向各worker進程發(fā)送信號,監(jiān)控worker進程的運行狀態(tài)赃份,當(dāng)worker進程退出后(異常情況下)寂拆,會自動重新啟動新的worker進程。

master進程充當(dāng)整個進程組與用戶的交互接口抓韩,同時對進程進行監(jiān)護纠永。它不需要處理網(wǎng)絡(luò)事件,不負責(zé)業(yè)務(wù)的執(zhí)行谒拴,只會通過管理worker進程來實現(xiàn)重啟服務(wù)尝江、平滑升級、更換日志文件英上、配置文件實時生效等功能炭序。

我們要控制nginx,只需要通過kill向master進程發(fā)送信號就行了苍日。比如kill -HUP pid惭聂,則是告訴nginx,從容地重啟nginx相恃,我們一般用這個信號來重啟nginx辜纲,或重新加載配置,因為是從容地重啟拦耐,因此服務(wù)是不中斷的耕腾。master進程在接收到HUP信號后是怎么做的呢?首先master進程在接到信號后杀糯,會先重新加載配置文件扫俺,然后再啟動新的worker進程,并向所有老的worker進程發(fā)送信號火脉,告訴他們可以光榮退休了牵舵。新的worker在啟動后柒啤,就開始接收新的請求,而老的worker在收到來自master的信號后畸颅,就不再接收新的請求担巩,并且在當(dāng)前進程中的所有未處理完的請求處理完成后,再退出没炒。當(dāng)然涛癌,直接給master進程發(fā)送信號,這是比較老的操作方式送火,nginx在0.8版本之后拳话,引入了一系列命令行參數(shù),來方便我們管理种吸。比如弃衍,./nginx -s reload,就是來重啟nginx坚俗,./nginx -s stop镜盯,就是來停止nginx的運行。如何做到的呢猖败?我們還是拿reload來說速缆,我們看到,執(zhí)行命令時恩闻,我們是啟動一個新的nginx進程艺糜,而新的nginx進程在解析到reload參數(shù)后,就知道我們的目的是控制nginx來重新加載配置文件了幢尚,它會向master進程發(fā)送信號破停,然后接下來的動作,就和我們直接向master進程發(fā)送信號一樣了侠草。

worker進程:

而基本的網(wǎng)絡(luò)事件辱挥,則是放在worker進程中來處理了。多個worker進程之間是對等的边涕,他們同等競爭來自客戶端的請求晤碘,各進程互相之間是獨立的。一個請求功蜓,只可能在一個worker進程中處理园爷,一個worker進程,不可能處理其它進程的請求式撼。worker進程的個數(shù)是可以設(shè)置的童社,一般我們會設(shè)置與機器cpu核數(shù)一致,這里面的原因與nginx的進程模型以及事件處理模型是分不開的著隆。

worker進程之間是平等的扰楼,每個進程呀癣,處理請求的機會也是一樣的。當(dāng)我們提供80端口的http服務(wù)時弦赖,一個連接請求過來项栏,每個進程都有可能處理這個連接,怎么做到的呢蹬竖?首先沼沈,每個worker進程都是從master進程fork過來,在master進程里面币厕,先建立好需要listen的socket(listenfd)之后列另,然后再fork出多個worker進程。所有worker進程的listenfd會在新連接到來時變得可讀旦装,為保證只有一個進程處理該連接页衙,所有worker進程在注冊listenfd讀事件前搶accept_mutex,搶到互斥鎖的那個進程注冊listenfd讀事件同辣,在讀事件里調(diào)用accept接受該連接拷姿。當(dāng)一個worker進程在accept這個連接之后,就開始讀取請求旱函,解析請求,處理請求描滔,產(chǎn)生數(shù)據(jù)后棒妨,再返回給客戶端,最后才斷開連接含长,這樣一個完整的請求就是這樣的了券腔。我們可以看到,一個請求拘泞,完全由worker進程來處理纷纫,而且只在一個worker進程中處理。worker進程之間是平等的陪腌,每個進程辱魁,處理請求的機會也是一樣的。當(dāng)我們提供80端口的http服務(wù)時诗鸭,一個連接請求過來染簇,每個進程都有可能處理這個連接,怎么做到的呢强岸?首先锻弓,每個worker進程都是從master進程fork過來,在master進程里面蝌箍,先建立好需要listen的socket(listenfd)之后青灼,然后再fork出多個worker進程暴心。所有worker進程的listenfd會在新連接到來時變得可讀,為保證只有一個進程處理該連接杂拨,所有worker進程在注冊listenfd讀事件前搶accept_mutex专普,搶到互斥鎖的那個進程注冊listenfd讀事件,在讀事件里調(diào)用accept接受該連接扳躬。當(dāng)一個worker進程在accept這個連接之后脆诉,就開始讀取請求,解析請求贷币,處理請求击胜,產(chǎn)生數(shù)據(jù)后,再返回給客戶端役纹,最后才斷開連接偶摔,這樣一個完整的請求就是這樣的了。我們可以看到促脉,一個請求辰斋,完全由worker進程來處理,而且只在一個worker進程中處理瘸味。

nginx的進程模型宫仗,可以由下圖來表示:

3.什么是FastCGI

FastCGI是一個可伸縮地、高速地在HTTP server和動態(tài)腳本語言間通信的接口旁仿。多數(shù)流行的HTTP server都支持FastCGI藕夫,包括Apache、Nginx和lighttpd等枯冈。同時毅贮,F(xiàn)astCGI也被許多腳本語言支持,其中就有PHP尘奏。

FastCGI是從CGI發(fā)展改進而來的滩褥。

CGI工作原理和缺點:

每次HTTP服務(wù)器遇到動態(tài)程序時都需要重新啟動腳本解析器來執(zhí)行解析,然后將結(jié)果返回給HTTP服務(wù)器炫加。

這在處理高并發(fā)訪問時幾乎是不可用的瑰煎。另外傳統(tǒng)的CGI接口方式安全性也很差,現(xiàn)在已經(jīng)很少使用了琢感。

FastCGI工作原理和優(yōu)點:

FastCGI接口方式采用C/S結(jié)構(gòu)丢间,可以將HTTP服務(wù)器和腳本解析服務(wù)器分開,同時在腳本解析服務(wù)器上啟動一個或者多個腳本解析守護進程驹针。當(dāng)HTTP服務(wù)器每次遇到動態(tài)程序時烘挫,可以將其直接交付給FastCGI進程來執(zhí)行,然后將得到的結(jié)果返回給瀏覽器。

這種方式可以讓HTTP服務(wù)器專一地處理靜態(tài)請求或者將動態(tài)腳本服務(wù)器的結(jié)果返回給客戶端饮六,這在很大程度上提高了整個應(yīng)用系統(tǒng)的性能其垄。

另外fastCGI程序與CGI程序與服務(wù)器的交互方式也不同

CGI程序通過環(huán)境變量、命令行卤橄、標準輸入輸出進行交互绿满,因此CGI程序進程必須與服務(wù)器進程在同一臺物理計算機上,而fastCGI程序與服務(wù)器進程通過網(wǎng)絡(luò)連接交互窟扑,因此fastCGI程序可以分布在不同的計算機上喇颁,這不但可以提高性能,同時也提高了系統(tǒng)的擴展能力嚎货。

4.什么是PHP-fpm

PHP-FPM是管理FastCGI的一個管理器橘霎,它作為PHP的插件存在,在安裝PHP要想使用PHP-FPM時在老php的老版本(php5.3.3之前)就需要把PHP-FPM以補丁的形式安裝到PHP中殖属,而且PHP要與PHP-FPM版本一致姐叁,這是必須的)

PHP-FPM是FastCGI的實現(xiàn),任何實現(xiàn)了FastCGI協(xié)議的Web Server都能夠與之通信洗显。FPM之于標準的FastCGI外潜,也提供了一些增強功能,具體可以參考官方文檔:PHP: FPM Installation挠唆。

FPM是一個PHP進程管理器处窥,包含master進程和worker進程兩種進程:master進程只有一個,負責(zé)監(jiān)聽端口玄组,接收來自Web Server的請求碧库,而worker進程則一般有多個(具體數(shù)量根據(jù)實際需要配置),每個進程內(nèi)部都嵌入了一個PHP解釋器巧勤,是PHP代碼真正執(zhí)行的地方,下圖是我本機上fpm的進程情況弄匕,1一個master進程颅悉,3個worker進程:


1一個master進程,3個worker進程

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

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

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

3.worker進程處理請求亡哄,如果超時枝缔,返回504錯誤

4.請求處理結(jié)束,返回結(jié)果

5.FastCGI子進程接著等待并處理來自FastCGI進程管理器(運行在 WebServer中)的下一個連接


4.那么Nginx,PHP-fpm和FastCGI是怎么的運行流程呢愿卸?

Nginx不支持對外部程序的直接調(diào)用或者解析灵临,所有的外部程序(包括PHP)必須通過FastCGI接口來調(diào)用。FastCGI接口在Linux下是socket(這個socket可以是文件socket趴荸,也可以是ip socket)儒溉。

1)、FastCGI進程管理器php-fpm自身初始化发钝,啟動主進程php-fpm和啟動start_servers個CGI 子進程顿涣。

主進程php-fpm主要是管理fastcgi子進程,監(jiān)聽9000(這個根據(jù)配置文件的監(jiān)聽端口改變而變)端口酝豪。

fastcgi子進程等待來自Web Server的連接涛碑。

2)、當(dāng)客戶端請求到達Web Server Nginx是時寓调,Nginx通過location指令锌唾,將所有以php為后綴的文件都交給127.0.0.1:9000來處理,即Nginx通過location指令夺英,將所有以php為后綴的文件都交給127.0.0.1:9000來處理晌涕。

3)FastCGI進程管理器PHP-FPM選擇并連接到一個子進程CGI解釋器。Web server將CGI環(huán)境變量和標準輸入發(fā)送到FastCGI子進程痛悯。

4)余黎、FastCGI子進程完成處理后將標準輸出和錯誤信息從同一連接返回Web Server。當(dāng)FastCGI子進程關(guān)閉連接時载萌,請求便告處理完成惧财。

5)、FastCGI子進程接著等待并處理來自FastCGI進程管理器(運行在 WebServer中)的下一個連接扭仁。

以上流程是根據(jù)下方配置文件來說明:


PHP-FPM的默認配置php-fpm.conf:

listen_address ?127.0.0.1:9000 #這個表示php的fastcgi進程監(jiān)聽的ip地址以及端口

start_servers

min_spare_servers

max_spare_servers

Nginx配置運行php:編輯nginx.conf加入如下語句:

location ~ \.php$ {

root html;

fastcgi_pass 127.0.0.1:9000;指定了fastcgi進程偵聽的端口,nginx就是通過這里與php交互的

fastcgi_index index.php;

include fastcgi_params;

fastcgi_param SCRIPT_FILENAME?? /usr/local/nginx/html$fastcgi_script_name;

}

Nginx通過location指令垮衷,將所有以php為后綴的文件都交給127.0.0.1:9000來處理,而這里的IP地址和端口就是FastCGI進程監(jiān)聽的IP地址和端口乖坠。


參考:

http://www.reibang.com/p/d0b858ed5030

http://www.reibang.com/p/a51a2d70e096

如有不正確之處搀突,麻煩指出改正。謝謝~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末熊泵,一起剝皮案震驚了整個濱河市仰迁,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌顽分,老刑警劉巖徐许,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異卒蘸,居然都是意外死亡雌隅,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來澄步,“玉大人冰蘑,你說我怎么就攤上這事〈甯祝” “怎么了祠肥?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長梯皿。 經(jīng)常有香客問我仇箱,道長,這世上最難降的妖魔是什么东羹? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任剂桥,我火速辦了婚禮,結(jié)果婚禮上属提,老公的妹妹穿的比我還像新娘权逗。我一直安慰自己,他們只是感情好冤议,可當(dāng)我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布斟薇。 她就那樣靜靜地躺著,像睡著了一般恕酸。 火紅的嫁衣襯著肌膚如雪堪滨。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天蕊温,我揣著相機與錄音袱箱,去河邊找鬼。 笑死义矛,一個胖子當(dāng)著我的面吹牛发笔,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播凉翻,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼筐咧,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了噪矛?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤铺罢,失蹤者是張志新(化名)和其女友劉穎艇挨,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體韭赘,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡缩滨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片脉漏。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡苞冯,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出侧巨,到底是詐尸還是另有隱情舅锄,我是刑警寧澤,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布司忱,位于F島的核電站皇忿,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏坦仍。R本人自食惡果不足惜鳍烁,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望繁扎。 院中可真熱鬧幔荒,春花似錦、人聲如沸梳玫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽汽纠。三九已至卫键,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間虱朵,已是汗流浹背莉炉。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留碴犬,地道東北人絮宁。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像服协,于是被迫代替她去往敵國和親绍昂。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,877評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 1. Nginx的模塊與工作原理 Nginx由內(nèi)核和模塊組成偿荷,其中窘游,內(nèi)核的設(shè)計非常微小和簡潔,完成的工作也非常簡單...
    rosekissyou閱讀 10,197評論 5 124
  • 第一章 Nginx簡介 Nginx是什么 沒有聽過Nginx跳纳?那么一定聽過它的“同行”Apache吧忍饰!Ngi...
    JokerW閱讀 32,642評論 24 1,002
  • FastCGI模塊模塊允許nginx同F(xiàn)astCGI協(xié)同工作,并且控制哪些參數(shù)將被安全傳遞寺庄。 一艾蓝、CGI和Fast...
    北山學(xué)者閱讀 9,163評論 3 8
  • Nginx簡介 解決基于進程模型產(chǎn)生的C10K問題,請求時即使無狀態(tài)連接如web服務(wù)都無法達到并發(fā)響應(yīng)量級一萬的現(xiàn)...
    魏鎮(zhèn)坪閱讀 1,991評論 0 9
  • 原文github地址 1.PHP概述 1.1 PHP的歷史發(fā)展 1995年由Lerdorf創(chuàng)建PHP力崇,高級腳本語言...
    10xjzheng閱讀 1,488評論 0 2