1. 程式人生 > >Nginx + fastcgi + php 的原理與關係

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伺服器的配置,可以看出,使用者訪問的是動態的php資源,nginx會呼叫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