1. 程式人生 > >Nginx與PHP的互動

Nginx與PHP的互動

Nginx是俄國人最早開發的Webserver,現在已經風靡全球,相信大家並不陌生。PHP也通過二十多年的發展來到了7系列版本,更加關注效能。這對搭檔在最近這些年,叱吒風雲,基本上LNMP成了當下的標配。可是,你用了這麼多年的Nginx+PHP的搭配,你真正知道他們之間是怎麼互動怎麼通訊的麼?作為一道常常用來面試的考題,從過往經驗看,情況並不樂觀。更多的同學是知道PHP-FPM、知道FastCGI,但不曉得Nginx、PHP這對老搭檔具體的互動細節。那麼,今天我們就來一起學習一下,做一回認真的PHP工程師。

前菜

為了講解的有理有據,我們先來準備一個純淨精簡的Nginx+PHP環境,這裡我們使用Docker拉取Centos最新版本環境,來快速通過編譯安裝方式搭建一個Nginx+PHP環境。(圖1,通過docker啟動一臺CentOS機器並進入)

有了Linux環境,我們來原始碼編譯安裝Nginx、PHP,這個過程網路裡有很多的教程,我們就不細說了。當然你也可以安裝lnmp一鍵安裝包來快速搭建。通過安裝nginx、php,我們的Linux環境裡就有了今天的這兩位主角了。我們稍加配置,讓Nginx可以接收請求並轉發給PHP-FPM,我們目標是輸出一個phpinfo()的資訊。(圖2,phpinfo()的輸出內容)

我們通過對Nginx新增Server配置實現了nginx與PHP的一次通訊,配置檔案非常簡單,如下圖:(圖3,一份nginx server配置)

有了上面的一個sample示例,我們開始深入Nginx與FastCGI協議。

主食

從上圖的Nginx配置中可以注意到 fastcgi* 開頭的一些配置,以及引入的 fastcgi.conf 檔案。其實在fastcgi.conf中,也是一堆fastcgi*的配置項,只是這些配置項相對不常變,通常單獨檔案保管可以在多處引用。(圖4,fastcgi.conf檔案中的內容)

可以看到在fastcgi.conf中,有很多的fastcgi_param配置,結合nginx server配置中的fastcgi_pass、fastcgi_index,通常我們的同學已經能夠想到Nginx與PHP之間打交道就是用的FastCGI,但再深問FastCGI是什麼?它起到銜接Nginx、PHP的什麼作用?等等深入的問題的時候,很多同學就卡殼了。那麼,我們就來一探究竟。

CGI是通用閘道器協議,FastCGI則是一種常住程序的CGI模式程式。我們所熟知的PHP-FPM的全稱是PHP FastCGI Process Manager,即PHP-FPM會通過使用者配置來管理一批FastCGI程序,例如在PHP-FPM管理下的某個FastCGI程序掛了,PHP-FPM會根據使用者配置來看是否要重啟補全,PHP-FPM更像是管理器,而真正銜接Nginx與PHP的則是FastCGI程序。(圖5,FastCGI在請求流中的位置)

如上圖所示,FastCGI的下游,是CGI-APP,在我們的LNMP架構裡,這個CGI-APP就是PHP程式。而FastCGI的上游是Nginx,他們之間有一個通訊載體,即圖中的socket。在我們上文圖3的配置檔案中,fastcgi_pass所配置的內容,便是告訴Nginx你接收到使用者請求以後,你該往哪裡轉發,在我們圖3中是轉發到本機的一個socket檔案,這裡fastcgi_pass也常配置為一個http介面地址(這個可以在php-fpm.conf中配置)。而上圖5中的Pre-fork,則對應著我們PHP-FPM的啟動,也就是在我們啟動PHP-FPM時便會根據使用者配置啟動諸多FastCGI觸發器(FastCGI Wrapper)。

對FastCGI在Nginx+PHP的模式中的定位有了一定了解後,我們再來了解下Nginx中為何能寫很多fastcgi_*的配置項。這是因為Nginx的一個預設內建module實現了FastCGI的Client。關於Module ngx_http_fastcgi_module的詳細文件可以檢視這裡: http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html 。我們關心一下我們圖4中的這些fastcgi_param都是些什麼吧,詳細描述見下圖。(圖6,nginx模組中fastcgi_param的介紹)

從圖6中可以看到,fastcgi_param所宣告的內容,將會被傳遞給“FastCGI server”,那這裡指的就是fastcgi_pass所指向的server,也就是我們Nginx+PHP模式下的PHP-FPM所管理的FastCGI程序,或者說是那個socket檔案載體。這時,有的同學會問:“為什麼PHP-FPM管理的那些FastCGI程序要關心這些引數呢?”,好問題,我們一起想想我們做PHP應用開發時候有沒有用到 $_SERVER 這個全域性變數,它裡面包含了很多伺服器的資訊,比如包含了使用者的IP地址。同學們不想想我們的PHP身處socket檔案之後,為什麼能得到遠端使用者的IP呢?聰明的同學應該注意到圖4中的一個fastcgi_param配置 REMOTE_ADDR ,這不正是我們在PHP中用 $_SERVER[‘REMOTE_ADDR’] 取到的使用者IP麼。的確,Nginx這個模組裡fastcgi_param引數,就是考慮後端程式有時需要獲取Webserver外部的變數以及伺服器情況,那麼ngx_http_fastcgi_module就幫我們做了這件事。真的是太感謝它啦!

那麼我們已經說清了FastCGI是個什麼東東,並且它在Nginx+PHP中的定位。我們回到前面提出的問題,“它起到銜接Nginx、PHP的什麼作用?”。

對PHP有一定了解的同學,應該會知道PHP提供SAPI面向Webserver來提供擴充套件程式設計。但是這樣的方式意味著你要是自主研發一套Webserver,你就需要學習SAPI,並且在你的Webserver程式中實現它。這意味著你的Webserver與PHP產生了耦合。在網際網路的大趨勢下,一般大家都不喜歡看到耦合。譬如Nginx在最初研發時候也不是為了和PHP組成黃金搭檔而研發的,相信早些年的Nginx後端程式可能是其他語言開發。那麼解決耦合的辦法,比較好的方式是有一套通用的規範,上下游都相容它。那麼CGI協議便成了Nginx、PHP都願意接受的一種方式,而FastCGI常住程序的模式又讓上下游程式有了高併發的可能。那麼,FastCGI的作用是Nginx、PHP的介面載體,就像插座與插銷,讓流行的WebServer與“世界上最好的語言”有了合作的可能。

有了這些基礎背景知識與他們的緣由,我們就可以舉一反三的做更多有意思的事情。譬如我在前年曾實現了Java程式中按照FastCGI Client的方式(替代Nginx)與PHP-FPM通訊,實現Java專案+PHP的一種組合搭配,解決的問題是Java程式一般來說在程式碼調整後需要編譯過程,而PHP可以隨時調整程式碼隨時生效,那麼讓Java作為專案外殼,一些易變的程式碼由PHP實現,在需要的時候Java程式通過FastCGI與PHP打交道就好。這套想法也是基於對Nginx+PHP互動模式的理解之上想到的。

網路中也有一些藉助FastCGI的嘗試與實踐,譬如《Writing Hello World in FCGI with C++》這篇文章,用C++實現一個FastCGI的程式,外部依然是某款Webserver來處理HTTP請求,但具體功能則有C++來實現,他們的中間互動同樣適用的FastCGI。同學們有興趣了也可以做些Geek嘗試。(圖7,C++實現一個FastCGI程式)

甜品

通過本文的講解,我們希望讓大家看到,Nginx+PHP的工程模式下,兩位主角分工明確,Nginx負責承載HTTP請求的響應與返回,以及超時控制記錄日誌等HTTP相關的功能,而PHP則負責處理具體請求要做的業務邏輯,它們倆的這種合作模式也是常見的分層架構設計中的一種,在它們各有專注面的同時,FastCGI又很好的將兩塊銜接,保障上下游通訊互動,這種通過某種協議或規範來銜接好上下游的模式,在我們日常的PHP應用開發中也有這樣的思想落地,譬如我們所開發的高效能API,具體的Client到底是PC、APP還是某個其他程式,我們不關心,而這些PC、APP、第三方程式也不關心我們的PHP程式碼實現,他們按照API的規範來請求做處理即可。同學們是不是發現技術思想是可以在各個環節融會貫通的,是不是很興奮?很刺激?哈,同學們開心就好,祝大家在工作學習過程中,能挖掘到更多的好知識,提升自己的同時造福身邊小夥伴!


作者:Pangee
連結:https://www.imooc.com/article/19278
來源:慕課網
本文原創釋出於慕課網 ,轉載請註明出處,謝謝合作

相關推薦

NginxPHP互動

Nginx是俄國人最早開發的Webserver,現在已經風靡全球,相信大家並不陌生。PHP也通過二十多年的發展來到了7系列版本,更加關注效能。這對搭檔在最近這些年,叱吒風雲,基本上LNMP成了當下的標配。可是,你用了這麼多年的Nginx+PHP的搭配,你真正知道他們之間是

Linux-rhel6.4 編譯安裝PHPNginxphp連接

linux php rhel 編譯安裝php 連接nginx 確定依賴包安裝gcc gcc-c++ libxml2 libxml2-devel bzip2 bzip2-devel libmcrypt libmcrypt-devel openssl openssl-devel libcurl

nginxphp-fpm原理

php-fpm 修改 連接 實現負載均衡 接收 請求 ams erro 目錄 一.正向代理與反向代理 1.正向代理:訪問google.com google.com vpn需要FQ才能訪問 vpn 對於我們來說是可以感知到的(我們連接vpn),但對於google服務

linux安裝nginxphp

ati 必須 解釋 spawn jit 選擇 ber dev 1.10 nginx安裝 本文是介紹使用源碼編譯安裝,包括具體的編譯參數信息。 正式開始前,編譯環境gcc g++ 開發庫之類的需要提前裝好。 安裝make: yum -y install gcc automa

nginxphp-fpm的運行方式?

php-fpmnginx與php-fpm是不是以多進程多線程方式運行的?Nginx 是非阻塞IO & IO復用模型,通過操作系統提供的類似 epoll 的功能,可以在一個線程裏處理多個客戶端的請求。Nginx 的進程就是線程,即每個進程裏只有一個線程,但這一個線程可以服務多個客戶端。PHP-FPM 是

LNP環境下NginxPHP配合解析的原理

發的 nag 自我 處理 php解析 系統 線程 指正 靜態 正在理解中,查閱資料,加上自我理解,得出如下結論,如有錯誤,歡迎指正。。。。 LNP環境,Nginx與PHP配合運行的原理解釋: 以前的互聯網時代我們成為web1.0時代,那時用戶是被動接受網絡信息,服務器上有什

nginxPHP配置

php-fpm roo fix ive string idt sysv def www 一、安裝依賴包 yum -y install libxml2 libxml2-devel openssl openssl-devel curl curl-devel libj

省市聯動jsphp互動

js 部分程式碼 - ajax <script> function f1(){ // sele1=document.getElementById('a').value var sele1 = $('#a').val(); $.ajax({ t

配置nginxphp-fpm踩過的坑,(附裝nginx,php-fpm,mysql,redis教程)

近來在centos7上搭建了lnmp的環境,遇到了個坑。如果沒有裝nmp的話可以看這個文章 https://blog.csdn.net/qq_39677681/article/details/82025445 我所遇到的坑: 要讓php-fpm能正常在伺服器上正常解析php,要配置這兩個

http server原理,nginxphp之間是如何工作的

Nginx (“engine x”) 是一個高效能的 HTTP 和 反向代理 伺服器,也是一個 IMAP/POP3/SMTP 代理伺服器。 Nginx 是由 Igor Sysoev 為俄羅斯訪問量第二的 Rambler.ru 站點開發的,第一個公開版本0.1.0釋出於2004年10月4日。其將原始碼

centos7下部署nginxphp

背景介紹 相信讀者在看這篇文章之前已經fastcgi,php-fpm有所瞭解。大概來講php語言需要fastcgi程式,即php直譯器解釋,而php直譯器需要php-fpm管理器進行排程。 以下對CGI、FastCGI、php-fpm之間關係進行通俗解釋(來源於知乎使用者Journey Lin): 講Fa

FastCGI特點原理、nginxphp-fpm兩種通訊方式對比

一、FastCGI特點: 1、HTTP伺服器和動態指令碼語言間通訊的介面或工具 2、可把動態語言解析和HTTP伺服器分離I 3、Nginx、Apache、Lighttpd,以及多數動態語言 都支援FastCGI 4、FastCGI介面方式採用 C/S結構,分為客戶端(

HTML5學習之九表單PHP互動

客戶端程式碼: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8">

H5表單PHP互動學習筆記

今日在網上觀看視訊學習H5,其中有幾個知識點不是很熟悉,所以打算寫下這篇部落格來記錄一下,以便將來再回來檢視! 該課程分為了三個小節來開展,內容如下: 1、html 5表單常用知識點 1.1單項選擇 1.2多項選擇 1.3下拉列表 1.4文字域 2、P

form表單php互動

1、用idea編輯如下表單form.html,其中action定義伺服器地址,method定義提交方式,提交方式有get和post兩種,get方式可以在位址列中看到提交資訊,post方式看不到,更安全。 <!DOCTYPE html> <header la

jqueryphp互動的ajax應用第一課:檢測使用者註冊時使用者名稱是否存在

當用戶註冊需要知道這個使用者名稱是否被人使用所以需要在使用者登陸前判斷 為了使使用者得到更好的體驗,我們使用了jquery的ajax效果,來使用者名稱是否存在。 首先需要一個新增年級的頁面,暫時叫grade.htm 這個檔案需要引入兩個檔案jquery.js(jquery

NginxPHP(php-fpm)工作機制及原理詳解

一、代理與反向代理 現實生活中的例子 1、正向代理:訪問google.com 如上圖,因為目前google已被和諧,我們需要vpn才能科學訪問google.com。 vpn對於“我們”來說,是可以感知到的(我們連線vpn)vpn對於”google伺服器”來說,是不可感知的(

AndroidPHP互動:客戶端用HTTP協議服務端通訊

        為了實現Android客戶端和服務端的通訊,Android SDK為我們提供了Apache的HttpClient來方便我們使用各種HTTP服務。可以把HttpClient看成一個瀏覽器,通過它可以方便地發出GET請求和POST請求來獲得服務端響應。 下面我們

nginxphp-fpm通訊方式

nginx和php-fpm的通訊方式有兩種,一種是tcp socket的方式,一種是unix socke方式。 tcp sockettcp socket的優點是可以跨伺服器,當nginx和php-fpm不在同一臺機器上時,只能使用這種方式。 unix socketUnix domain socket 又叫

jQuery的Cookie封裝,PHP互動

首先,用到兩個jQuery函式,JSON.parse(Json字串轉物件)和JSON.stringify(物件轉JSON字串) 我這裡的分成兩次封裝,因為資料不在一個頁面裡。 這是第一個頁面: $(".color-gray").click(function(){ va