PHP關於進程池的優化

本文打算從另外一個角度來討論問題,教你們如何配置高效的環境,如此一樣可以達到優化的目的。php

pool

一個讓人沮喪的消息是絕大多數 PHP 程序員都忽視了池的價值。這裏所說的池可不是指數據庫鏈接池之類的東西,而是指進程池,PHP 容許同時啓動多個池,每一個池使用不一樣的配置,各個池之間尊重彼此的主權領土完整,互不干涉內政。nginx

-pool程序員

有什麼好處呢?默認狀況下,PHP 只啓用了一個池,全部請求均在這個池中執行。一旦某些請求出現擁堵之類的狀況,那麼極可能會連累整個池出現火燒赤壁的結局;若是啓用多個池,那麼能夠把請 求分門別類放到不一樣的池中執行,此時若是某些請求出現擁堵之類的狀況,那麼只會影響本身所在的池,從而控制故障的波及範圍。數據庫

listen

雖然 Nginx 和 PHP 能夠部署在不一樣的服務器上,可是實際應用中,多數人都習慣把它們部署在同一臺服務器上,如此就有兩個選擇:一個是 TCP,另外一個是 Unix Socket。服務器

-listen併發

和 TCP 比較,Unix Socket 省略了一些諸如 TCP 三次握手之類的環節,因此相對更高效,不過須要注意的是,在使用 Unix Socket 時,由於沒有 TCP 對應的可靠性保證機制,因此最好把 backlog 和 somaxconn 設置大些,不然面對高併發時會不穩定。高併發

pm

進程管理有動態和靜態之分。動態模式通常先啓動少許進程,再按照請求數的多少實時調整進程數。如此的優勢很明顯:節省資源;固然它的缺點也很明顯: 一旦出現高併發請求,系統將不得不忙着 FORK 新進程,必然會影響性能。相對應的,靜態模式一次性 FORK 足量的進程,以後無論請求量如何均保持不變。和動態模式相比,靜態模式雖然消耗了更多的資源,可是面對高併發請求,它不須要執行高昂的 FORK。php-fpm

-pmpost

對大流量網站而言,除非服務器資源緊張,不然靜態模式無疑是最佳選擇。性能

pm.max_children

啓動多少個 PHP 進程合適?在你給出本身的答案以前,不妨看看下面的文章:

一個 CPU 在某一個時刻只能處理一個請求。當請求數大於 CPU 個數時,CPU 會劃分時間片,輪流執行各個請求,既然涉及多個任務的調度,那麼上下文切換必然會消耗一部分性能,從這個意義上講,進程數應該等於 CPU 個數,如此一來每一個進程都對應一個專屬的 CPU,能夠把上下文切換損失的效率降到最低。不過這個結論僅在請求是 CPU 密集型時纔是正確的,而對於通常的 Web 請求而言,多半是 IO 密集型的,此時這個結論就值得商榷了,由於數據庫查詢等 IO 的存在,必然會致使 CPU 有至關一部分時間處於 WAIT 狀態,也就是被浪費的狀態。此時若是進程數多於 CPU 個數的話,那麼當發生 IO 時,CPU 就有機會切換到別的請求繼續執行,雖然這會帶來必定上下文切換的開銷,可是總比卡在 WAIT 狀態好多了。

那多少合適呢?要理清這個問題,咱們除了要關注 CPU 以外,還要關注內存狀況:

-PHP Memory

如上所示 top 命令的結果中和內存相關的列分別是 VIRT,RES,SHR。其中 VIRT 表示的是內存佔用的理論值,一般不用在乎它,RES 表示的是內存佔用的實際值,雖然 RES 看上去很大,可是包含着共享內存,也就是 SHR 顯示的值,因此單個 PHP 進程實際獨立佔用的內存大小等於「RES – SHR」,通常就是 10M 上下。以此推算,理論上 1G 內存能支撐大概一百個 PHP 進程,10G 內存能大概支撐一千個 PHP 進程。固然並不能粗暴認爲越多越好,最好結合 PHP 的 status 接口,經過監控活躍鏈接數的數量來調整。

 

原文出處: 火丁筆記(@火丁筆記)  

相關文章
相關標籤/搜索