Nginx 與 PHP 交互拢肆?

NGINX

Nginx是俄國人最早開發(fā)的Webserver减响,現(xiàn)在已經(jīng)風(fēng)靡全球靖诗,相信大家并不陌生。PHP也通過二十多年的發(fā)展來到了7系列版本支示,更加關(guān)注性能刊橘。這對(duì)搭檔在最近這些年,叱咤風(fēng)云颂鸿,基本上LNMP成了當(dāng)下的標(biāo)配促绵。可是嘴纺,你用了這么多年的Nginx+PHP的搭配败晴,你真正知道他們之間是怎么交互怎么通信的么?作為一道常常用來面試的考題颖医,從過往經(jīng)驗(yàn)看位衩,情況并不樂觀。更多的同學(xué)是知道PHP-FPM熔萧、知道FastCGI,但不曉得Nginx僚祷、PHP這對(duì)老搭檔具體的交互細(xì)節(jié)佛致。那么,今天我們就來一起學(xué)習(xí)一下辙谜,做一回認(rèn)真的PHP工程師俺榆。

前菜

為了講解的有理有據(jù),我們先來準(zhǔn)備一個(gè)純凈精簡的Nginx+PHP環(huán)境装哆,這里我們使用Docker拉取Centos最新版本環(huán)境罐脊,來快速通過編譯安裝方式搭建一個(gè)Nginx+PHP環(huán)境。(圖1蜕琴,通過docker啟動(dòng)一臺(tái)CentOS機(jī)器并進(jìn)入)

docker

有了Linux環(huán)境萍桌,我們來源碼編譯安裝Nginx、PHP凌简,這個(gè)過程網(wǎng)絡(luò)里有很多的教程上炎,我們就不細(xì)說了。當(dāng)然你也可以安裝lnmp一鍵安裝包來快速搭建雏搂。通過安裝nginx藕施、php,我們的Linux環(huán)境里就有了今天的這兩位主角了凸郑。我們稍加配置裳食,讓Nginx可以接收請(qǐng)求并轉(zhuǎn)發(fā)給PHP-FPM,我們目標(biāo)是輸出一個(gè)phpinfo()的信息芙沥。(圖2诲祸,phpinfo()的輸出內(nèi)容)

php

我們通過對(duì)Nginx新增Server配置實(shí)現(xiàn)了nginx與PHP的一次通信尘盼,配置文件非常簡單,如下圖:(圖3烦绳,一份nginx server配置)

nginx

有了上面的一個(gè)sample示例卿捎,我們開始深入Nginx與FastCGI協(xié)議。

主食

從上圖的 Nginx 配置中可以注意到 fastcgi* 開頭的一些配置径密,以及引入的 fastcgi.conf 文件午阵。其實(shí)在 fastcgi.conf 中,也是一堆 fastcgi* 的配置項(xiàng)享扔,只是這些配置項(xiàng)相對(duì)不常變底桂,通常單獨(dú)文件保管可以在多處引用。(圖4惧眠,fastcgi.conf 文件中的內(nèi)容)

可以看到在 fastcgi.conf 中籽懦,有很多的 fastcgi_param 配置,結(jié)合 nginx server 配置中的 fastcgi_pass氛魁、fastcgi_index暮顺,通常我們的同學(xué)已經(jīng)能夠想到 Nginx與PHP之間打交道就是用的 FastCGI,但再深問 FastCGI 是什么秀存?它起到銜接Nginx捶码、PHP的什么作用?等等深入的問題的時(shí)候或链,很多同學(xué)就卡殼了惫恼。

那么,我們就來一探究竟澳盐。CGI 是通用網(wǎng)關(guān)協(xié)議祈纯,F(xiàn)astCGI 則是一種常住進(jìn)程的 CGI 模式程序。我們所熟知的 PHP-FPM的全稱是 PHP FastCGI Process Manager叼耙,即 PHP-FPM 會(huì)通過用戶配置來管理一批 FastCGI 進(jìn)程腕窥,例如在PHP-FPM管理下的某個(gè) FastCGI 進(jìn)程掛了,PHP-FPM 會(huì)根據(jù)用戶配置來看是否要重啟補(bǔ)全旬蟋,PHP-FPM更像是管理器油昂,而真正銜接 Nginx 與 PHP 的則是 FastCGI 進(jìn)程。(圖5倾贰,F(xiàn)astCGI在請(qǐng)求流中的位置)

CGI

如上圖所示冕碟,F(xiàn)astCGI 的下游,是 CGI-APP匆浙,在我們的 LNMP 架構(gòu)里安寺,這個(gè) CGI-APP 就是 PHP 程序。而 FastCGI 的上游是 Nginx首尼,他們之間有一個(gè)通信載體挑庶,即圖中的 socket言秸。在我們上文圖3的配置文件中,fastcgi_pass 所配置的內(nèi)容迎捺,便是告訴 Nginx 你接收到用戶請(qǐng)求以后举畸,你該往哪里轉(zhuǎn)發(fā),在我們圖3中是轉(zhuǎn)發(fā)到本機(jī)的一個(gè) socket 文件凳枝,這里 fastcgi_pass 也常配置為一個(gè)
http 接口地址(這個(gè)可以在 php-fpm.conf 中配置)抄沮。而上圖5中的 Pre-fork,則對(duì)應(yīng)著我們 PHP-FPM 的啟動(dòng)岖瑰,也就是在我們啟動(dòng)PHP-FPM時(shí)便會(huì)根據(jù)用戶配置啟動(dòng)諸多FastCGI觸發(fā)器(FastCGI Wrapper)叛买。

對(duì) FastCGI 在 Nginx+PHP 的模式中的定位有了一定了解后,我們?cè)賮砹私庀?Nginx 中為何能寫很多 fastcgi_* 的配置項(xiàng)蹋订。這是因?yàn)?Nginx 的一個(gè)默認(rèn)內(nèi)置 module 實(shí)現(xiàn)了 FastCGI 的 Client率挣。關(guān)于 Module ngx_http_fastcgi_module的詳細(xì)文檔可以查看這里: http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html 。我們關(guān)心一下我們圖4中的這些 fastcgi_param 都是些什么吧露戒,詳細(xì)描述見下圖椒功。(圖6,nginx 模塊中 fastcgi_param 的介紹)

nginx 模塊中 fastcgi_param 的介紹

從圖6中可以看到玫锋,fastcgi_param所聲明的內(nèi)容蛾茉,將會(huì)被傳遞給“FastCGI server”,那這里指的就是fastcgi_pass所指向的server撩鹿,也就是我們Nginx+PHP模式下的PHP-FPM所管理的FastCGI進(jìn)程,或者說是那個(gè)socket文件載體悦屏。這時(shí)节沦,有的同學(xué)會(huì)問:“為什么PHP-FPM管理的那些FastCGI進(jìn)程要關(guān)心這些參數(shù)呢?”础爬,好問題甫贯,我們一起想想我們做PHP應(yīng)用開發(fā)時(shí)候有沒有用到 $_SERVER 這個(gè)全局變量,它里面包含了很多服務(wù)器的信息看蚜,比如包含了用戶的IP地址叫搁。同學(xué)們不想想我們的PHP身處socket文件之后,為什么能得到遠(yuǎn)端用戶的IP呢供炎?聰明的同學(xué)應(yīng)該注意到圖4中的一個(gè)fastcgi_param配置 REMOTE_ADDR 渴逻,這不正是我們?cè)赑HP中用 $_SERVER[‘REMOTE_ADDR’] 取到的用戶IP么。的確音诫,Nginx這個(gè)模塊里fastcgi_param參數(shù)惨奕,就是考慮后端程序有時(shí)需要獲取Webserver外部的變量以及服務(wù)器情況,那么ngx_http_fastcgi_module就幫我們做了這件事竭钝。真的是太感謝它啦梨撞!

那么我們已經(jīng)說清了FastCGI是個(gè)什么東東雹洗,并且它在Nginx+PHP中的定位。我們回到前面提出的問題卧波,“它起到銜接Nginx时肿、PHP的什么作用?”港粱。

對(duì)PHP有一定了解的同學(xué)螃成,應(yīng)該會(huì)知道PHP提供SAPI面向Webserver來提供擴(kuò)展編程。但是這樣的方式意味著你要是自主研發(fā)一套Webserver啥容,你就需要學(xué)習(xí)SAPI锈颗,并且在你的Webserver程序中實(shí)現(xiàn)它。這意味著你的Webserver與PHP產(chǎn)生了耦合咪惠。在互聯(lián)網(wǎng)的大趨勢(shì)下击吱,一般大家都不喜歡看到耦合。譬如Nginx在最初研發(fā)時(shí)候也不是為了和PHP組成黃金搭檔而研發(fā)的遥昧,相信早些年的Nginx后端程序可能是其他語言開發(fā)覆醇。那么解決耦合的辦法,比較好的方式是有一套通用的規(guī)范炭臭,上下游都兼容它永脓。那么CGI協(xié)議便成了Nginx、PHP都愿意接受的一種方式鞋仍,而FastCGI常住進(jìn)程的模式又讓上下游程序有了高并發(fā)的可能常摧。那么,F(xiàn)astCGI的作用是Nginx威创、PHP的接口載體落午,就像插座與插銷,讓流行的WebServer與“世界上最好的語言”有了合作的可能肚豺。

有了這些基礎(chǔ)背景知識(shí)與他們的緣由溃斋,我們就可以舉一反三的做更多有意思的事情。譬如我在前年曾實(shí)現(xiàn)了Java程序中按照FastCGI Client的方式(替代Nginx)與PHP-FPM通信吸申,實(shí)現(xiàn)Java項(xiàng)目+PHP的一種組合搭配梗劫,解決的問題是Java程序一般來說在代碼調(diào)整后需要編譯過程,而PHP可以隨時(shí)調(diào)整代碼隨時(shí)生效截碴,那么讓Java作為項(xiàng)目外殼梳侨,一些易變的代碼由PHP實(shí)現(xiàn),在需要的時(shí)候Java程序通過FastCGI與PHP打交道就好隐岛。這套想法也是基于對(duì)Nginx+PHP交互模式的理解之上想到的猫妙。

網(wǎng)絡(luò)中也有一些借助FastCGI的嘗試與實(shí)踐,譬如《Writing Hello World in FCGI with C++》這篇文章聚凹,用C++實(shí)現(xiàn)一個(gè)FastCGI的程序割坠,外部依然是某款Webserver來處理HTTP請(qǐng)求齐帚,但具體功能則有C++來實(shí)現(xiàn),他們的中間交互同樣適用的FastCGI彼哼。同學(xué)們有興趣了也可以做些Geek嘗試对妄。(圖7,C++實(shí)現(xiàn)一個(gè)FastCGI程序)

C++實(shí)現(xiàn)一個(gè)FastCGI程序

甜品

通過本文的講解敢朱,我們希望讓大家看到剪菱,Nginx+PHP的工程模式下,兩位主角分工明確拴签,Nginx負(fù)責(zé)承載HTTP請(qǐng)求的響應(yīng)與返回孝常,以及超時(shí)控制記錄日志等HTTP相關(guān)的功能,而PHP則負(fù)責(zé)處理具體請(qǐng)求要做的業(yè)務(wù)邏輯蚓哩,它們倆的這種合作模式也是常見的分層架構(gòu)設(shè)計(jì)中的一種构灸,在它們各有專注面的同時(shí),F(xiàn)astCGI又很好的將兩塊銜接岸梨,保障上下游通信交互喜颁,這種通過某種協(xié)議或規(guī)范來銜接好上下游的模式,在我們?nèi)粘5腜HP應(yīng)用開發(fā)中也有這樣的思想落地曹阔,譬如我們所開發(fā)的高性能API半开,具體的Client到底是PC、APP還是某個(gè)其他程序赃份,我們不關(guān)心寂拆,而這些PC、APP抓韩、第三方程序也不關(guān)心我們的PHP代碼實(shí)現(xiàn)漓库,他們按照API的規(guī)范來請(qǐng)求做處理即可。同學(xué)們是不是發(fā)現(xiàn)技術(shù)思想是可以在各個(gè)環(huán)節(jié)融會(huì)貫通的园蝠,是不是很興奮?很刺激痢士?哈彪薛,同學(xué)們開心就好,祝大家在工作學(xué)習(xí)過程中怠蹂,能挖掘到更多的好知識(shí)善延,提升自己的同時(shí)造福身邊小伙伴!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末城侧,一起剝皮案震驚了整個(gè)濱河市易遣,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌嫌佑,老刑警劉巖豆茫,帶你破解...
    沈念sama閱讀 218,858評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件侨歉,死亡現(xiàn)場離奇詭異,居然都是意外死亡揩魂,警方通過查閱死者的電腦和手機(jī)幽邓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來火脉,“玉大人牵舵,你說我怎么就攤上這事【牍遥” “怎么了畸颅?”我有些...
    開封第一講書人閱讀 165,282評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長方援。 經(jīng)常有香客問我没炒,道長,這世上最難降的妖魔是什么肯骇? 我笑而不...
    開封第一講書人閱讀 58,842評(píng)論 1 295
  • 正文 為了忘掉前任窥浪,我火速辦了婚禮,結(jié)果婚禮上笛丙,老公的妹妹穿的比我還像新娘漾脂。我一直安慰自己,他們只是感情好胚鸯,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評(píng)論 6 392
  • 文/花漫 我一把揭開白布骨稿。 她就那樣靜靜地躺著,像睡著了一般姜钳。 火紅的嫁衣襯著肌膚如雪坦冠。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,679評(píng)論 1 305
  • 那天哥桥,我揣著相機(jī)與錄音辙浑,去河邊找鬼。 笑死拟糕,一個(gè)胖子當(dāng)著我的面吹牛判呕,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播送滞,決...
    沈念sama閱讀 40,406評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼侠草,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼!你這毒婦竟也來了犁嗅?” 一聲冷哼從身側(cè)響起边涕,我...
    開封第一講書人閱讀 39,311評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后功蜓,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體园爷,經(jīng)...
    沈念sama閱讀 45,767評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年霞赫,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了腮介。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,090評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡端衰,死狀恐怖叠洗,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情旅东,我是刑警寧澤灭抑,帶...
    沈念sama閱讀 35,785評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站抵代,受9級(jí)特大地震影響腾节,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜荤牍,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評(píng)論 3 331
  • 文/蒙蒙 一案腺、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧康吵,春花似錦劈榨、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至惭载,卻和暖如春旱函,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背描滔。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評(píng)論 1 271
  • 我被黑心中介騙來泰國打工棒妨, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人含长。 一個(gè)月前我還...
    沈念sama閱讀 48,298評(píng)論 3 372
  • 正文 我出身青樓靶衍,卻偏偏與公主長得像,于是被迫代替她去往敵國和親茎芋。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評(píng)論 2 355

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

  • 1. Nginx的模塊與工作原理 Nginx由內(nèi)核和模塊組成蜈出,其中田弥,內(nèi)核的設(shè)計(jì)非常微小和簡潔,完成的工作也非常簡單...
    rosekissyou閱讀 10,215評(píng)論 5 124
  • CGI 通用網(wǎng)關(guān)接口(Common Gateway Interface)是一個(gè)Web服務(wù)器主機(jī)提供信息服務(wù)的標(biāo)準(zhǔn)接...
    沒我找不到電子書閱讀 1,934評(píng)論 1 4
  • Nginx的工作原理 1.Nginx的模塊與工作原理 Nginx由內(nèi)核和模塊組成铡原,其中偷厦,內(nèi)核的設(shè)計(jì)非常微小和簡潔商叹,...
    架構(gòu)飛毛腿閱讀 6,027評(píng)論 1 27
  • 更改ip和dnsVi /etc/sysconfig/network-scripts/ifcfg-eth0vi /...
    Xwei_閱讀 1,822評(píng)論 0 3
  • Nginx簡介 解決基于進(jìn)程模型產(chǎn)生的C10K問題,請(qǐng)求時(shí)即使無狀態(tài)連接如web服務(wù)都無法達(dá)到并發(fā)響應(yīng)量級(jí)一萬的現(xiàn)...
    魏鎮(zhèn)坪閱讀 2,005評(píng)論 0 9