首頁 >後端開發 >php教程 >聊聊Nginx與php-fpm的通訊機制,看看如何設定?

聊聊Nginx與php-fpm的通訊機制,看看如何設定?

青灯夜游
青灯夜游轉載
2022-03-08 10:38:176028瀏覽

本篇文章帶大家聊聊Nginx與php-fpm的通訊機制,介紹一下兩種通訊方式的不同,看看Nginx 與php-fpm 的結合要怎麼配置,分析一下應用中如何選擇通訊方式,希望能夠給大家幫忙!

聊聊Nginx與php-fpm的通訊機制,看看如何設定?

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 解譯器,是程式碼真正執行的地方。

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 socket 和unix socket 兩種方式。

tcp socket 的優點是可以跨伺服器,當 nginx 和 php-fpm 不在同一台機器上時,只能使用這種方式。

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

兩種方式的資料傳輸過程如下圖所示:

#二者的不同:

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

Nginx 與php-fpm 結合只需要在各自的設定檔中做設定即可:

1) Nginx 中的設定

以tcp socket通訊為例

server {
    listen       80; #监听 80 端口,接收http请求
    server_name  www.test.com; #就是网站地址
    root /usr/local/etc/nginx/www/huxintong_admin; # 准备存放代码工程的路径
    #路由到网站根目录 www.test.com 时候的处理
    location / {
        index index.php; #跳转到 www.test.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 的通訊。

在應用程式中的選擇

如果是在同一台伺服器上執行的nginx 和php-fpm,且並發量不高(不超過1000),選擇unix socket,以提高nginx和php-fpm 的通訊效率。
如果是面臨高並發業務,則考慮選擇使用更可靠的 tcp socket,以負載平衡、核心最佳化等維運手段維持效率。

若併發較高但仍想用 unix socket 時,可透過以下方式提高 unix socket 的穩定性。

1)將sock檔案放在 /dev/shm 目錄下,此目錄下將 sock 檔案放在記憶體裡面,記憶體的讀寫更快。

2)提高 backlog

backlog 預設位元 128,1024 這個值最好換算成自己正常的 QPS,配置如下。

nginx.conf 檔案中

server {
        listen 80 default backlog = 1024;
       }

php-fpm.conf 檔案中

listen.backlog = 1024

3)增加sock 檔案和php-fpm 實例

#在/ dev/shm 新建一個sock 文件,在nginx 中透過upstream 模組將請求負載平衡到兩個sock 文件,並且將兩個sock 文件分別對應到兩套php-fpm 實例上。

推薦學習:《PHP影片教學

以上是聊聊Nginx與php-fpm的通訊機制,看看如何設定?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:segmentfault.com。如有侵權,請聯絡admin@php.cn刪除