參考連接:php
- https://www.zhihu.com/question/64414628 php fpm 進程數和併發數是什麼關係?html
- https://segmentfault.com/q/1010000005942449/a-1020000012063637 php不支持多線程因此不用考慮併發問題?web
- http://bbs.csdn.net/topics/390778072 PHP是單線程的,如何應對大量的http訪問? #9層回答segmentfault
- http://www.javashuo.com/article/p-kynzncpi-dk.html PHP 線程,進程和併發服務器
- https://segmentfault.com/q/1010000000256516 搞不清FastCgi與PHP-fpm之間是個什麼樣的關係多線程
- http://php.net/manual/zh/install.fpm.php FastCGI 進程管理器(FPM)併發
- http://www.javashuo.com/article/p-amsihzzj-cx.html 多線程(一)高併發和多線程的關係高併發
首先搞清楚php-fpm與cgi的關係php-fpm
cgi是一個web server與cgi程序(這裏能夠理解爲是php解釋器)之間進行數據傳輸的協議,保證了傳遞的是標準數據。性能
php-cgi是php解釋器,就是上文提到的cgi程序。
Fastcgi是用來提升cgi程序(php-cgi)性能的方案/協議。
cgi程序的性能問題在哪呢?"PHP解析器會解析php.ini文件,初始化執行環境",就是這裏了。標準的CGI對每一個請求都會執行這些步驟,因此處理的時間會比較長。
Fastcgi會先啓一個master,解析配置文件,初始化執行環境,而後再啓動多個worker。當請求過來時,master會傳遞給一個worker,而後當即能夠接受下一個請求。這樣就避免了重複勞動,效率天然提升。並且當worker不夠用時,master能夠根據配置預先啓動幾個worker等着;固然空閒worker太多時,也會停掉一些,這樣就提升了性能,也節約了資源。這就是Fastcgi的對進程的管理。
上文提到了Fastcgi只是一個方案或者協議,那麼php-fpm就是這個實現了Fastcgi的程序,也就是說,上文所描述的進程分配和管理是FPM來作的。官方對FPM的解釋是 Fastcgi Process Manager(Fastcgi 進程管理器) 。
PHP對併發訪問的處理
PHP從代碼級別來說不支持多線程操做,不能像Java、C#等語言同樣能夠編寫多線程代碼。但多線程和併發沒有直接關係,多線程只是代碼被運行時在同一時間同時執行多個線程任務,來提升服務器CPU的利用率,提升代碼效率。但php是能夠多進程執行的,上文所述的FPM進程管理機制就是多進程單線程的,有效提升了併發訪問的響應效率。
1. 當客戶端發送一個請求時,web server會經過一個php-fpm進程(這裏和下文所說指的fpm進程都是fpm開啓的worker進程,關於fpm的工做原理這裏再也不累述)去執行php代碼,php代碼的執行是單線程的。
2. 那麼,當有多個客戶端同時發送請求時(併發),web server會經過php-fpm爲每一個請求開啓一個單獨進程去執行php代碼。
3. 請求執行事後,空閒的php-fpm進程被銷燬,內存得以釋放。
4. 但併發的問題在於,在某一時間,客戶端請求讓php-fpm進程數量達到了最大限制數,這個時候,新來的請求只能等待空閒的php-fpm進程來處理,這就是多進程同步阻塞模式的弊端,固然還有進程過多所帶來的內存佔用問題。