官方手冊:FPM(FastCGI 進程管理器)用於替換 PHP FastCGI 的大部分附加功能,對於高負載網站是很是有用的。
它的功能包括:php
從官方手冊來看,php-fpm是一個FastCGI的進程管理器,用來管理FastCGI進程的。
那麼什麼是FastCGI呢?這個咱們要從CGI提及。html
CGI (Common Gateway Interface)是 Web Server 與後臺語言交互的協議,有了這個協議,開發者可使用任何語言處理 Web Server 發來的請求,動態的生成內容。保證了傳遞過來的數據是標準格式的(規定了以什麼樣的格式傳哪些數據(URL、查詢字符串、POST數據、HTTP header等等)),方便了開發者。nginx
PHP語言對應與服務器交互的CGI程序就是PHP-CGI。
CGI程序自己只能解析請求、返回結果,不會進程管理,因此有一個致命的缺點,那就是每處理一個請求都須要fork一個全新的進程,隨着Web的興起,高併發愈來愈成爲常態,這樣低效的方式明顯不能知足需求(每一次web請求都會有啓動和退出進程,也就是最爲人詬病的fork-and-execute模式,這樣一在大規模併發下,就死翹翹了)。就這樣,FastCGI誕生了,CGI程序很快就退出了歷史的舞臺。web
FastCGI,顧名思義爲更快的 CGI,它容許在一個進程內處理多個請求,而不是一個請求處理完畢就直接結束進程,性能上有了很大的提升。FastCGI也能夠說是一種協議segmentfault
首先,FastCGI會先啓一個master進程,解析配置文件,初始化執行環境,而後再啓動多個worker進程。當請求過來時,master會傳遞給一個worker,而後當即能夠接受下一個請求。
這樣就避免了重複的勞動,效率天然是高。
並且當worker不夠用時,master能夠根據配置預先啓動幾個worker等着。
固然空閒worker太多時,也會停掉一些,這樣就提升了性能,也節約了資源。這就是FastCGI的對進程的管理。瀏覽器
那如今咱們能夠大體上想象到php-fpm是個什麼東東了吧!緩存
FPM 是一個 PHP 進程管理器,包含 master 進程和 worker 進程兩種進程:master 進程只有一個,負責監聽端口,接收來自 Web Server 的請求,而 worker 進程則通常有多個 (具體數量根據實際須要配置),每一個進程內部都嵌入了一個 PHP 解釋器,是 PHP 代碼真正執行的地方,下面是我本機上FPM的進程狀況:1個master進程,2個worker進程。bash
1.FPM的master進程接收到請求。
2.master進程根據配置指派特定的worker進程進行請求處理,若是沒有可用進程,返回錯誤,這也是咱們配合Nginx遇到502錯誤比較多的緣由。
3.worker進程處理請求,若是超時,返回504錯誤。
4.請求處理結束,返回結果。服務器
FPM從接收處處理請求的流程就是這樣了,那麼Nginx
又是如何發送請求給FPM的呢?併發
咱們知道,Nginx 不只僅是一個 Web 服務器,也是一個功能強大的 proxy 服務器,除了進行 http 請求的代理,也能夠進行許多其餘協議請求的代理,包括本文與 fpm 相關的 fastcgi 協議。爲了可以使 Nginx 理解 fastcgi 協議,Nginx 提供了 fastcgi 模塊來將 http 請求映射爲對應的 fastcgi 請求。
Nginx的FastCGI模塊提供了fastcgi_param指令來主要處理這些映射關係,下面 是Nginx的一個配置文件實例,其主要完成的工做是將Nginx中的變量翻譯成PHP中可以理解的變量。
除此以外,很是重要的就是fastcgi_pass指令了,這個指令用於指定FPM進程監聽的地址,Nginx會把全部的PHP請求翻譯成FastCGI請求以後再發送到這個地址。下面一個簡單的能夠工做的Nginx配置文件:
server { listen 80; server_name www.example.com; root /usr/local/web/Mr_J/public; index index.php index.html index.htm; access_log /usr/local/nginx/logs/test-access.log; error_log /usr/local/nginx/logs/test-error.log; location / { try_files $uri $uri/ /index.php?$query_string; } location ~\.php$ { fastcgi_pass 127.0.0.1; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } }
在這個配置文件中,咱們新建了一個虛擬主機,監聽80端口,項目根目錄爲 /usr/local/web/Mr_J/public。而後咱們經過location指令,將全部的以.php結尾的請求都交給FastCGI模塊處理,從而把全部的PHP請求都交給了FPM處理,從而完成Nginx到FPM的閉環。
如此以來,Nginx與FPM通訊的整個流程應該比較清晰了。
www.example.com | | Nginx | | 路由到www.example.com/index.php | | 加載nginx的fast-cgi模塊 | | fast-cgi監聽127.0.0.1:9000地址 | | www.example.com/index.php請求到達127.0.0.1:9000 | | php-fpm 監聽127.0.0.1:9000 | | php-fpm 接收到請求,啓用worker進程處理請求 | | php-fpm 處理完請求,返回給nginx | | nginx將結果經過http返回給瀏覽器
Nginx+Php-fpm運行原理詳解
理解 Nginx 與 PHP-FPM 通訊的工做機制
CGI、FastCGI和PHP-FPM關係圖解