一個master進程,支援多個pool,每個pool由master進程監聽不同的連接埠,pool中有多個worker進程.
每個worker進程都內建PHP解釋器,並且進程常駐後台,支援prefork動態增加.
每個worker進程支援在執行時間編譯腳本並在記憶體中快取產生的opcode來提升效能.
每個worker進程支援設定回應指定請求數後自動重新啟動,master進程會重新啟動掛掉的worker進程.
每個worker進程能保持一個到MySQL/Memcached/Redis的持久連接,實現"連接池",避免重複建立連接,對程序透明.
使用數據庫持久連接時應該設定固定數量的worker進程數,不要使用動態的prefork模式.
master進程採用epoll模型異步接收和分發請求,listen監聽端口,epoll_wait等待連接,
然後分發給對應pool裡的worker進程等待連接,
然後分發給對應pool裡的worker進程等待連接,
然後分發給對應pool裡的worker進程等待連接, worker進程accpet請求後poll處理連接,
如果worker進程不夠用,master進程會prefork更多進程,
如果prefork達到了pm.max_childrenmaster,worker進程又全都繁忙, 如果prefork達到了pm.max_childrenmaster,worker進程又全都繁忙,
進程會把請求掛起到連線佇列backlog裡(預設值是511).
1個PHP-FPM工作進程在同一時刻裡只能處理1個請求.
MySQL的最大連線數max_connections預設是151.
只要PHP-FPM工作進程數不超過151,就不會出現連接不上MySQL的情況.
而且正常情況下,也不需要開啟那麼多的PHP-FPM工作進程,
而且正常情況下,也不需要開啟那麼多的PHP-FPM工作進程,
例如4個PHP-FPM進程就能跑滿4個核心的CPU,
那麼你開40個PHP-FPM進程也沒有任何意義,
只會佔用更多的內存,造成更多的CPU上下文切換,效能反而更差.
為了減少每個請求都重複建立和釋放連接的開銷,可以開啟持久連接,
一個PHP-FPM進程保持一個到MySQL的長連接,實現透明的"連接池".
Nginx跟PHP-FPM分開,其實是很好的解耦,PHP-FPM專門負責處理PHP請求,一個頁面對應一個PHP請求,
頁面中所有靜態資源的請求都由Nginx來處理,這樣就實現了動靜分離,而Nginx最擅長的就是處理高並發.
PHP-FPM是一個多進程的FastCGI服務,類似Apache的prefork的進程模型,
對於只處理PHP請求來說,這個模型是很高效很穩定的.
不像Apache(libphp.so),一個頁面,要處理多個請求,包括圖片,樣式表,JS腳本,PHP腳本等.
php-fpm從5.3開始才進入PHP原始碼主幹,之前版本沒有php-fpm.
那時的spawn-fcgi是一個需要調用php-cgi的FastCGI進程管理器,
另外像Apache的mod_fcgid和IIS的PHP Manager也需要呼叫php-cgi進程,
但php-fpm則根本不依賴php-cgi,完全獨立運行,也不依賴php(cli)命令列解釋器.
因為php-fpm是內建了php解釋器的FastCGI服務,啟動時能夠自行讀取php.ini配置和php-fpm.conf配置.
個人認為,PHP-FPM工作進程數,設定為2倍CPU核心數就夠了.
畢竟,Nginx和MySQL以及系統同樣要消耗CPU.
根據伺服器記憶體來設定PHP-FPM進程數非常不合理,
把記憶體分配給記憶體分配給記憶體分配給,Linux磁碟快取(buffers/cache)這些服務顯然更合適.
過多的PHP-FPM進程反而會增加CPU上下文切換的開銷.
PHP程式碼中應該盡量避免curl或_get_contents這些file可能會產生較長網絡I/O耗時的代碼.
注意設置CURLOPT_CONNECTTIMEOUT_MS超時時間,避免進程被長時間阻塞.
如果要異步執行耗時較長的任務,可以pclose(popen('/path/ to/task.php &', 'r')); 開啟一個行程來處理,
或藉助訊息佇列,總之就是要盡量避免阻塞到PHP-FPM工作流程.
在php-fpm.conf中把request_slowlog_timeout設為1秒,在slowlog中查看是否有耗時超過1秒的代碼.
優化代碼,能夠為所有PHP-FPM工作進程減負,這個才是提高性能的根本方法.
能讓CPU滿載運作的操作可以視為CPU密集型操作.
上傳和下載則是典型的I/O密集型操作,因為耗時主要發生在網路I/O和磁碟I/O. 🎜 🎜🎜需要PHP認證的下載作業可以委託為Nginx的AIO線程池: 🎜🎜🎜header("X-Accel-Redirect: $file_path"); 🎜🎜至於上傳操作,例如可以建立一個監聽9001埠的名為upload的PHP-FPM進程池(pool),
專門負責處理上傳操作(透過Nginx分發),避免上傳操作阻塞到監聽9000埠的計算密集的www進程池.
這時upload進程池多開點進程也無所謂:
[www]
listen = 127.0.0.1:90005 = 4
[upload]
listen = 127.0.0.1:9001
pmren
pm.min_spare_servers = 4
pm.max_spare_servers = 4
利用PHP-FPM提供的池的隔離性,分離計算密集和I/O密集操作,可以減少阻塞對整個PHP應用的影響.
。
以上就介紹了PHP FastCGI進程管理器PHP-FPM的架構,包含了面向的內容,希望對PHP教學有興趣的朋友有幫助。