Nginx + fastcgi + php 的原理與關係
- CGI:Common Gateway Interface 公共閘道器介面,web伺服器和指令碼語言通訊的一個標準、介面、協議【協議】
- FastCGI:CGI協議的升級版【協議】
- PHP-CGI: 實現了CGI介面協議的PHP指令碼解析器【程式】
- PHP-FPM: 管理和排程php-cgi程序,進而實現了FastCGI介面協議的程式【程式】
問題:CGI對每個請求會parse一遍對應指令碼的配置檔案(如php.ini),
載入配置和擴充套件,初始化執行環境,效能非常差,所有有了下面的流程:
那麼實現Fastcgi協議的程式,如PHP-FPM是怎麼做的呢?首先,Fastcgi會先啟一個master程序,解析配置檔案,初始化執行環境,然後再啟動多個worker程序,這個worker就是php-cgi。當請求過來時,master會傳遞給一個worker,然後立即可以接受下一個請求。這樣就避免了重複的勞動,效率自然是高。而且當worker不夠用時,master可以根據配置預先啟動幾個worker等著,比如20worker,當然空閒worker太多時,也會停掉一些,這樣就提高了效能,也節約了資源。這就是fastcgi的對程序的管理。
結合 使用者對動態PHP網頁訪問過程來理解
第一步:使用者將http請求傳送給nginx伺服器
第二步:nginx會根據使用者訪問的URI和字尾對請求進行判斷
1.例如使用者訪問的index.php,nginx則會根據配置檔案中的location進行匹配,例如:
root@json:/data/web# cat /etc/nginx/conf.d/blog.conf server { root /data/web/blog/; index index.html index.htm; server_name www.fwait.com; location / { try_files $uri $uri/ /index.html; } location /blog/ { #alias /usr/share/doc/; auth_basic "authorized users only"; auth_basic_user_file /etc/nginx/passwd.conf; #autoindex on; allow 192.168.1.103; deny all; } location ~ \.php$ { include /etc/nginx/fastcgi_params; fastcgi_intercept_errors on; fastcgi_pass 127.0.0.1:9000; } }
使用者訪問的是index.php,則會匹配到location ~ \.php$,這個的含義是對使用者通過URI訪問的資源進行區分大小的匹配,並且訪問的資源是以.php結尾的。
nginx根據使用者請求的資源匹配到具體的location後,會執行location對應的動作,location中動作的含義是:
include /etc/nginx/fastcgi_params; #表示nginx會呼叫fastcgi這個介面
fastcgi_intercept_errors on; #表示開啟fastcgi的中斷和錯誤資訊記錄
fastcgi_pass 127.0.0.1:9000; # 表示nginx通過fastcgi_pass將使用者請求的資源發給127.0.0.1:9000進行解析,這裡的nginx和php指令碼解析伺服器是在同一臺機器上,所以127.0.0.1:9000表示的就是本地的php指令碼解析伺服器。
第三步:通過第二步可以看出,使用者請求的是動態內容,nginx會將請求交給fastcgi客戶端,通過fastcgi_pass將使用者的請求傳送給php-fpm
如果使用者訪問的是靜態資源呢,那就簡單了,nginx直接將使用者請求的靜態資源返回給使用者。
第四步:fastcgi_pass將動態資源交給php-fpm後,php-fpm會將資源轉給php指令碼解析伺服器的wrapper
第五步:wrapper收到php-fpm轉過來的請求後,wrapper會生成一個新的執行緒呼叫php動態程式解析伺服器
如果使用者請求的是需要讀取例如MySQL資料庫等,將會觸發讀庫操作;
如果使用者請求的是如圖片/附件等,PHP會觸發一次查詢後端儲存伺服器如通過NFS進行儲存的儲存叢集;
第六步:php會將查詢到的結果返回給nginx
第七步:nginx構造一個響應報文將結果返回給使用者
這只是nginx的其中一種,使用者請求的和返回使用者請求結果是非同步進行,即為使用者請求的資源在nginx中做了一次中轉,nginx可以同步,即為解析出來的資源,伺服器直接將資源返回給使用者,不用在nginx中做一次中轉。
用一張圖表示 nginx fastcgi wrapper php之間的關係:一圖勝千言
&n