PHP-FPM 與 Nginx 的通信機制總結

PHP-FPM 介紹

  • CGI 協議與 FastCGI 協議

每種動態語言( PHP,Python 等)的代碼文件需要通過對應的解析器才能被服務器識別,而 CGI 協議就是用來使解釋器與服務器可以互相通信。PHP 文件在服務器上的解析需要用到 PHP 解釋器,再加上對應的 CGI 協議,從而使服務器可以解析到 PHP 文件。

由於 CGI 的機制是每處理一個請求需要 fork 一個 CGI 進程,請求結束再kill掉這個進程,在實際應用上比較浪費資源,於是就出現了CGI 的改良版本 FastCGI,FastCGI 在請求處理完後,不會 kill 掉進程,而是繼續處理多個請求,這樣就大大提高了效率。

  • PHP-FPM 是什麼

PHP-FPM 即 PHP-FastCGI Process Manager, 它是 FastCGI 的實現,並提供了進程管理的功能。進程包含 master 進程和 worker 進程兩種;master 進程只有一個,負責監聽端口,接收來自服務器的請求,而 worker 進程則一般有多個(具體數量根據實際需要進行配置),每個進程內部都會嵌入一個 PHP 解釋器,是代碼真正執行的地方。

<!--more-->

Nginx 與 php-fpm 通信機制

當我們訪問一個網站(如 www.test.com)的時候,處理流程是這樣的:

  www.test.com
        |
        |
      Nginx
        |
        |
路由到www.test.com/index.php
        |
        |
加載nginx的fast-cgi模塊
        |
        |
fast-cgi監聽127.0.0.1:9000地址
        |
        |
www.test.com/index.php請求到達127.0.0.1:9000
        |
        |
     等待處理...
  • Nginx 與 php-fpm 結合

在 Linux 上,Nginx 與 php-fpm 的通信有 tcp 和 unix socket 兩種方式。

tcp 的優點是可以跨服務器,當 Nginx 和 PHP-fpm 不在同一臺機器上時,只能使用這種方式。

Unix socket 又叫 IPC(inter-process communication 進程間通信) socket,用於實現同一主機上的進程間通信,這種方式需要在 nginx配置文件中填寫 php-fpm 的 socket 文件位置。

兩種方式的數據傳輸過程如下圖所示:

二者的不同:

由於 Unix socket 不需要經過網絡協議棧,不需要打包拆包、計算校驗和、維護序號和應答等,只是將應用層數據從一個進程拷貝到另一個進程。所以其效率比 tcp 的方式要高,可減少不必要的 tcp 開銷。不過,Unix socket 高併發時不穩定,連接數爆發時,會產生大量的長時緩存,在沒有面向連接協議的支撐下,大數據包可能會直接出錯不返回異常。而 tcp 這樣的面向連接的協議,可以更好的保證通信的正確性和完整性。

Nginx 與 php-fpm 結合只需要在各自的配置文件中做設置即可:

1) Nginx 中的配置

以 tcp 通信爲例

server {
    listen       80; #監聽80端口,接收http請求
    server_name  www.example.com; #就是網站地址
    root /usr/local/etc/nginx/www/huxintong_admin; # 準備存放代碼工程的路徑
    #路由到網站根目錄www.example.com時候的處理
    location / {
        index index.php; #跳轉到www.example.com/index.php
        autoindex on;
    }   

    #當請求網站下php文件的時候,反向代理到php-fpm
    location ~ \.php$ {
        include /usr/local/etc/nginx/fastcgi.conf; #加載nginx的fastcgi模塊
        fastcgi_intercept_errors on;
        fastcgi_pass   127.0.0.1:9000; # tcp 方式,PHP-fpm 監聽的IP地址和端口
       # fasrcgi_pass /usr/run/php-fpm.sock # unix socket 連接方式
    }

}

2) php-fpm 的配置

listen = 127.0.0.1:9000
# 或者下面這樣
listen = /var/run/php-fpm.sock
注意,在使用 Unix socket 方式連接時,由於 socket 文件本質上是一個文件,存在權限控制的問題,所以需要注意 Nginx 進程的權限與 php-fpm 的權限問題,不然會提示無權限訪問。(在各自的配置文件裏設置用戶)

通過以上配置即可完成 php-fpm 與 Nginx 的通信。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章