每種動態語言( PHP,Python 等)的代碼文件須要經過對應的解析器才能被服務器識別,而 CGI 協議就是用來使解釋器與服務器能夠互相通訊。PHP 文件在服務器上的解析須要用到 PHP 解釋器,再加上對應的 CGI 協議,從而使服務器能夠解析到 PHP 文件。php
因爲 CGI 的機制是每處理一個請求須要 fork 一個 CGI 進程,請求結束再kill掉這個進程,在實際應用上比較浪費資源,因而就出現了CGI 的改良版本 FastCGI,FastCGI 在請求處理完後,不會 kill 掉進程,而是繼續處理多個請求,這樣就大大提升了效率。nginx
PHP-FPM 即 PHP-FastCGI Process Manager, 它是 FastCGI 的實現,並提供了進程管理的功能。進程包含 master 進程和 worker 進程兩種;master 進程只有一個,負責監聽端口,接收來自服務器的請求,而 worker 進程則通常有多個(具體數量根據實際須要進行配置),每一個進程內部都會嵌入一個 PHP 解釋器,是代碼真正執行的地方。緩存
當咱們訪問一個網站(如 www.test.com)的時候,處理流程是這樣的:bash
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
|
|
等待處理...
複製代碼
在 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 這樣的面向鏈接的協議,能夠更好的保證通訊的正確性和完整性。socket
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 鏈接方式
}
}
複製代碼
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 實例上。