首頁  >  文章  >  後端開發  >  PHP FastCGI進程管理器PHP-FPM的架構

PHP FastCGI進程管理器PHP-FPM的架構

WBOY
WBOY原創
2016-07-29 09:07:571372瀏覽

PHP FastCGI进程管理器PHP-FPM的架构

一個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 
pmren
pm.min_spare_servers = 4 
pm.max_spare_servers = 4 
利用PHP-FPM提供的池的隔離性,分離計算密集和I/O密集操作,可以減少阻塞對整個PHP應用的影響. 

以上就介紹了PHP FastCGI進程管理器PHP-FPM的架構,包含了面向的內容,希望對PHP教學有興趣的朋友有幫助。

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn