## **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
|
|
location 到 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 的配置
php-fpm.conf
~~~
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 實例上。
- Apache
- 【Apache運維基礎(1)】Apache的安裝與使用
- 【Apache運維基礎(2)】主配置文件說明
- 【Apache運維基礎(3)】虛擬主機配置說明
- 【Apache運維基礎(4)】Apache的Rewrite攻略(1)
- 【Apache運維基礎(5)】Apache的Rewrite攻略(2).htaccess文件
- 【Apache運維基礎(6)】Apache的日志管理與分析
- 工具篇
- supervisor進程管理器
- Haproxy安裝與配置
- Nginx
- 【nginx網站性能優化篇(1)】gzip壓縮與expire瀏覽器緩存
- 【nginx網站性能優化篇(2)】反向代理實現Apache與Nginx的動靜分離(LNMPA)
- 【nginx網站性能優化篇(3)】反向代理實現負載均衡
- 【nginx網站性能優化篇(4)】理解nginx的高并發原理及其配置調優
- 【nginx運維基礎(1)】Nginx的編譯安裝與使用
- 【nginx運維基礎(2)】Nginx的配置文件說明及虛擬主機配置示例
- 【nginx運維基礎(3)】Nginx的編譯PHP
- 【nginx運維基礎(4)】Nginx的日志管理(日志格式與定時分割日志)
- 【nginx運維基礎(5)】Nginx的location攻略
- 【nginx運維基礎(6)】Nginx的Rewrite語法詳解
- 【nginx運維基礎(7)】配置SSL支持https訪問
- 【nginx運維基礎(8)】配置支持http2協議
- 【nginx運維基礎(9)】了解PHP-FPM 與 Nginx 的通信機制
- 其它
- Apache與Nginx下php隱藏http頭部版本信息的實現方法
- CURL與PHP-CLI的應用【CLI篇】
- CURL與PHP-CLI的應用【Curl篇】
- Linux之SAMBA共享服務
- 【Linux常識篇(1)】所謂的正向代理與反向代理
- 【Linux常識篇(2)】理解inode
- 【Linux常識篇(3)】文件及文件夾的ctime atime mtime的含義詳解
- centOS使用手記
- 服務器日志分析
- 高頻命令
- df
- mv
- gzip
- cp
- tar
- touch
- cat
- uniq
- nl
- more
- rmdir
- less
- mkdir
- head
- rm
- tail
- 五大查詢命令
- vi&vim
- ls與目錄結構
- grep
- awk
- sed
- 其他高頻命令