淺析PHP-FPM、CGI、Fast CGI的關係

做爲一個phper,一直會接觸到php、nignx等的相關配置,相關的名詞好比PHP-FPM、CGI、Fast CGI、SAPI等等應該都或多或少接觸過,但本身對於這些知識點的掌握其實相對比較分散且造成不了必定的關係,因而在網上搜了相關的文章並結合本身的一些理解,整理成此文,便於記錄。php

首先,先看一個最簡單的服務器請求和響應的流程html

1.jpg

在這個例子中,Web Server(如Nginx)只是內容的分發者,若是客戶端請求的是 index.html等靜態文件,那麼Web Server會去文件系統中找到這個文件,發送給瀏覽器,這裏分發的是靜態數據。nginx

2.jpg

若是請求的是php文件,nginx沒法直接處理,就會去配置文件nginx中尋找是否有對於php文件的配置shell

server
    {
        listen 80 default_server;
        server_name _;
        index index.html index.htm index.php;
        root  /home/wwwroot/test/public;
        #error_page   404   /404.html;

        location ~ [^/]\.php(/|$)
        {
            try_files $uri =404;
            fastcgi_pass  unix:/tmp/php-cgi.sock;
            fastcgi_index index.php;
            include fastcgi.conf;
        }
...

在nginx.conf文件中,你們能夠發現有這麼一段配置,若是是php文件的請求,就會分發到這個邏輯中。apache

這裏定義的是與php解析器進行通信的一些配置參數,其中fastcgi_pass參數約定了nginx和php進行通信的socket是unix:/tmp/php-cgi.sock,後文會講到php同時也會對應的監聽這個端口瀏覽器

PS:部分配置文件中這個地址會是一個IP+端口號的TCP形式,TCP能夠跨服務器,而UNIX Domain Socket不通過網絡層,只能用於Nginx跟PHP-FPM都在同一服務器的場景

這樣子友誼的小橋就這樣順利的搭建起來了。如今小橋搭建好了,剩下的就是通信的數據格式的統一了,這時候須要用到Fast-cgi協議,這個協議約定了這二者通信的數據格式服務器

CGI:是 Web Server 與 Web Application 之間數據交換的一種協議,由於其每次請求都要執行fork-and-execut的流程,因此存在較大的性能瓶頸,如今已經不多使用

FastCGI:同 CGI,是一種通訊協議,但比 CGI 在效率上作了一些優化,採用了常駐(long-live)型來減小系統的開銷,使得性能大大提高網絡

前面說過Fast CGI只是一種協議(看到有很多文章會將這是一個應用程序,實際上是不對的),那遵循這個協議的實現者就是咱們熟悉的PHP-FPM(FastCGI Process Manager),它的架構是由一個manager進程負責管理一個進程池,進程池中就是子進程php-cgi架構

打開php安裝目錄下的php-fpm.conf,能夠看到有如下一段參數配置socket

listen = /tmp/php-cgi.sock
listen.backlog = -1
listen.allowed_clients = 127.0.0.1
listen.owner = www

能夠看到php-fpm下一樣監聽了/tmp/php-cgi.sock這個socket,這和前面nginx.conf的配置是對應的

因而請求最後就交由到FastCGI子進程來進行處理,FastCGI子進程完成處理後,將標準輸出和錯誤信息從同一鏈接返回Web Server進行輸出

因此一個php請求的自上而下的流程以下圖:

PHP與nginx交互流程圖_愛奇藝.jpg

這裏有一個名詞放在文末將可能會更加的便於理解,你們能夠看到我在圖中將CGI包含在一個叫SAPI的類型下,那什麼是SAPI呢?下面的解釋引用至鳥哥的博客

SAPI: Server abstraction API,研究過PHP架構的同窗應該知道這個東東的重要性,它提供了一個接口,使得PHP能夠和其餘應用進行交互數據

前面咱們講過的Fast CGI,還有其餘好比shell的CLI,以及apache的mod_php5,都屬於SAPI的範疇,目的是爲了讓各個服務器抽象層之間遵照着相同的約定,使php自己和上層應用解耦隔離,使php的可移植性更強。

參考文章:
深刻理解Zend SAPIs(Zend SAPI Internals)
CGI、FastCGI和PHP-FPM關係圖解
你肯定你真的懂Nginx與PHP的交互?

相關文章
相關標籤/搜索