⑴ php-fpm怎麼連接的mysql
們都知道,php是不能直接操作 mysql的,他需要通過擴展提供介面調用,php的mysql擴展也好幾個,只支持面向過程的mysql,既支持面向過程也支持面向對象的mysqli,只支持面向對象的PDO,當然無論是那個擴展,也只是php語法寫法上的區別而已,底層其實是一樣的。
今天我們不講語法這些老掉牙的東西,我們隨便找一個擴展,來分析一下 php底層 和 mysql 之間的通信原理。
首先我們來理解一下 php-fpm 的工作原理,php-fpm 是一個 php-cgi 進程管理器,其實就是一個連接池,它和nginx配合的工作原理如下。
我們先從最簡單的靜態方式入手觀察他的工作原理
vim php-fpm.ini
[www]
pm = static
pm.max_children = 5
pm.max_requests = 2
上面三句話的含義是什麼呢:
1、static 表示靜態以靜態方式生成 php-fpm 進程
2、pm.max_children = 5 表示當 php-fpm 啟動時就啟動 5 個 php-fpm 子進程 等待處理 nginx 發過來的請求
3、pm.max_requests = 2 表示每個 php-fpm 子進程處理 2 個請求就銷毀,當然父進程每次看到有銷毀的自然也就會生成新的子進程
我們來簡單驗證一下這個說法:
首先重啟 php-fpm,讓它復位一下
接下來寫一條簡單的語句輸出當前進程ID
echo "當前 php-fpm 進程ID:".posix_getpid();
不斷刷新瀏覽器觀察輸出變化
當前 php-fpm 進程ID:24548
當前 php-fpm 進程ID:24549
當前 php-fpm 進程ID:24550
當前 php-fpm 進程ID:24547
當前 php-fpm 進程ID:24551
當前 php-fpm 進程ID:24548
當前 php-fpm 進程ID:24549
當前 php-fpm 進程ID:24550
當前 php-fpm 進程ID:24547
當前 php-fpm 進程ID:24551
當前 php-fpm 進程ID:24563
當前 php-fpm 進程ID:24564
當前 php-fpm 進程ID:24565
當前 php-fpm 進程ID:24566
當前 php-fpm 進程ID:24567
當前 php-fpm 進程ID:24563
當前 php-fpm 進程ID:24564
當前 php-fpm 進程ID:24565
當前 php-fpm 進程ID:24566
當前 php-fpm 進程ID:24567
當前 php-fpm 進程ID:24568
當前 php-fpm 進程ID:24569
當前 php-fpm 進程ID:24570
當前 php-fpm 進程ID:24571
當前 php-fpm 進程ID:24572
當前 php-fpm 進程ID:24568
當前 php-fpm 進程ID:24569
當前 php-fpm 進程ID:24570
當前 php-fpm 進程ID:24571
當前 php-fpm 進程ID:24572
可以看得出,第一批id不是按照順序執行的,進程id為24547的進程是在第四位處理的,然後從下面開始,所有id都是順序執行的而且每次生成的一批id都是遞增,是不是有種mysql自增主鍵的趕腳呢?
這里需要注意的是,無論是靜態還是下面的動態配置方式,只要沒有設置 max_requests ,那麼進程是不會銷毀的,也就是說當一個進程裡面出現死循環或者內存溢出等導致進程僵死的情況出現的時候,處理的進程就會少一個了
好吧理解了靜態的處理方式,我們其實也很容易知道這個方式的弊端了,當然我們平時伺服器不可能就開5個進程每個進程處理2個請求,我們來做一個簡單的加減乘除,看看一個伺服器應該開多少個 php-fpm 合適
首先我們來看看一個簡單的echo需要多少內存:
$size = memory_get_usage();
$unit = array('b','kb','mb','gb','tb','pb');
$memory = @round($size/pow(1024,($i=floor(log($size,1024)))),2).' '.$unit[$i];
echo "當前 php-cgi 進程所使用內存:".$memory;
觀察瀏覽器我們可以得到一下數據:
當前 php-cgi 進程所使用內存:227.17 kb
也就是說一個簡單的什麼都不幹的php就已經佔用了200多K的內存,當然這也不算多。
不過進程多了cpu切換進程速度就會變慢,所以這個數還是需要通過ab等測試工具才能測試出具體應該開多少比較合理
我們先從200開始,不斷的增加,架設增加到800的時候,效率和400一樣,那我們就沒必要開800那麼多進程浪費內存了。
那麼問題就來了,如果同一時間請求出超過400呢?有人說會排隊等待,真的會排隊等待嗎?答案明顯是 php-fpm 是沒能力排隊了,因為處理請求的php-fpm子進程都用完了,那麼等待也就只能是在 nginx 等待,通常一個 nginx 也不只是轉發請求給 php-fpm 就完事了,他還要處理靜態文件呢?如果這些php請求導致nginx的請求數過多一直在等待,那麼訪問靜態文件自然也會卡了,這時候我們就需要配置成下面的動態處理方式。
[www]
pm.max_children = 10
pm.start_servers = 5
pm.min_spare_servers = 2
pm.max_spare_servers = 8
;pm.max_requests = 2
上面五句話的含義是什麼呢:
1、dynamic 表示靜態以動態方式生成 php-fpm 進程
2、pm.max_children = 10 同時活動的進程數 10個
3、pm.start_servers = 5 表示當 php-fpm 主進程啟動時就啟動 5 個 php-fpm 子進程
4、pm.min_spare_servers = 2 表示最小備用進程數
5、pm.max_spare_servers = 8 表示最大備用進程數
6、pm.max_requests = 2 上面說過就不說了
當前 php-fpm 進程ID:2270
當前 php-fpm 進程ID:2271
當前 php-fpm 進程ID:2272
當前 php-fpm 進程ID:2273
當前 php-fpm 進程ID:2274
當前 php-fpm 進程ID:2270
當前 php-fpm 進程ID:2271
當前 php-fpm 進程ID:2272
當前 php-fpm 進程ID:2273
當前 php-fpm 進程ID:2274
當前 php-fpm 進程ID:2270
當前 php-fpm 進程ID:2271
當前 php-fpm 進程ID:2272
當前 php-fpm 進程ID:2273
當前 php-fpm 進程ID:2274
⑵ 說說php-fpm配置解析
PHP-FPM配置解析
在編譯安裝PHP時,通過在./configure中添加參數`--enable-fpm`即可開啟PHP-FPM。配置文件為`php-fpm.conf`,其語法類似`php.ini`。默認位置為`/usr/local/php/etc/php-fpm.conf`,若未在此處,可能位於`/usr/local/php/etc/php-fpm.d/`目錄下。
全局配置包含PID文件路徑、錯誤日誌位置及錯誤級別設置。
進程池配置允許定義多個進程池,通過設置監聽地址與埠來接受FastCGI請求。推薦使用Unix域Socket,如配置`listen/tmp/php-cgi.sock`以提高性能,適合高並發場景,盡管在不穩定時可設置`backlog`以管理連接隊列。
`listen.allowed_clients`允許訪問FastCGI進程的IP白名單,設置為`any`則不限制IP訪問。
進程管理器設置包括`pm`參數選擇靜態、動態或按需管理子進程數量,`pm.max_children`和`pm.start_servers`定義進程最大數量與起始數量,確保穩定性與資源利用。
內存管理考慮:對於大內存伺服器(8G以上),建議使用靜態設置以提升效率。而小內存伺服器(如1G)則有利於系統穩定,合理分配資源。
`request_terminate_timeout`與`request_slowlog_timeout`分別設置最大執行時間與慢請求記錄,有助於調試與優化。
慢日誌功能通過設置`request_slowlog_timeout`來記錄超過指定時間的請求,包括進程號、腳本名稱、執行時間等詳細信息,幫助排查問題。
配置修改後,執行`sudo systemctl restart php-fpm`以使更改生效。
希望以上內容能幫助您理解並應用PHP-FPM配置,更多學習資源可關注公眾號:PHP開源社區,或訪問我們整理的精華文章合集,覆蓋框架、微服務、分布式、高並發與資料庫等PHP技術領域。
⑶ php-fpm子進程會自動重啟嗎
伺服器出現異常,網站不能正常訪問。經排查�php的問題。
在重啟php-fpm時,恢復正常。1分鍾之後又出現故障。查看php日誌文件/usr/local/php/var/log 後提示
WARNING: [pool www] server reached pm.max_children setting (5), consider raising it
子進程數已經達到設置的最大值。
要設置php進程數量。需要在php-fpm.conf文件中修改。
先看/usr/local/php/etc/php-fpm.conf文件各項配置解析
pid = run/php-fpm.pid
#pid設置,默認在安裝目錄中的var/run/php-fpm.pid,建議開啟
error_log = log/php-fpm.log
#錯誤日誌,默認在安裝目錄中的var/log/php-fpm.log
log_level = notice
#錯誤級別. 可用級別為: alert(必須立即處理), error(錯誤情況), warning(警告情況), notice(一般重要信息), debug(調試信息). 默認: notice.
emergency_restart_threshold = 60
emergency_restart_interval = 60s
#表示在emergency_restart_interval所設值內出現SIGSEGV或者SIGBUS錯誤的php-cgi進程數如果超過 emergency_restart_threshold個,php-fpm就會優雅重啟。這兩個選項一般保持默認值。
process_control_timeout = 0
#設置子進程接受主進程復用信號的超時時間. 可用單位: s(秒), m(分), h(小時), 或者 d(天) 默認單位: s(秒). 默認值: 0.
daemonize = yes
#後台執行fpm,默認值為yes,如果為了調試可以改為no。在FPM中,可以使用不同的設置來運行多個進程池。 這些設置可以針對每個進程池單獨設置。
listen = 127.0.0.1:9000
#fpm監聽埠,即nginx中php處理的地址,一般默認值即可。可用格式為: 『ip:port』, 『port』, 『/path/to/unix/socket』. 每個進程池都需要設置.
listen.backlog = -1
#backlog數,-1表示無限制,由操作系統決定,此行注釋掉就行。backlog含義參考:
http://www.3gyou.cc/?p=41
listen.allowed_clients = 127.0.0.1
#允許訪問FastCGI進程的IP,設置any為不限制IP,如果要設置其他主機的nginx也能訪問這台FPM進程,listen處要設置成本地可被訪問的IP。默認值是any。每個地址是用逗號分隔. 如果沒有設置或者為空,則允許任何伺服器請求連接
listen.owner = www
listen.group = www
listen.mode = 0666
#unix socket設置選項,如果使用tcp方式訪問,這里注釋即可。
user = www
group = www
#啟動進程的帳戶和組
pm = dynamic #對於專用伺服器,pm可以設置為static。
#如何控制子進程,選項有static和dynamic。如果選擇static,則由pm.max_children指定固定的子進程數。如果選擇dynamic,則由下開參數決定:
pm.max_children #,子進程最大數
pm.start_servers #,啟動時的進程數
pm.min_spare_servers #,保證空閑進程數最小值,如果空閑進程小於此值,則創建新的子進程
pm.max_spare_servers #,保證空閑進程數最大值,如果空閑進程大於此值,此進行清理
pm.max_requests = 1000
#設置每個子進程重生之前服務的請求數. 對於可能存在內存泄漏的第三方模塊來說是非常有用的. 如果設置為 』0′ 則一直接受請求. 等同於 PHP_FCGI_MAX_REQUESTS 環境變數. 默認值: 0.
pm.status_path = /status
#FPM狀態頁面的網址. 如果沒有設置, 則無法訪問狀態頁面. 默認值: none. munin監控會使用到
ping.path = /ping
#FPM監控頁面的ping網址. 如果沒有設置, 則無法訪問ping頁面. 該頁面用於外部檢測FPM是否存活並且可以響應請求. 請注意必須以斜線開頭 (/)。
ping.response = pong
#用於定義ping請求的返回相應. 返回為 HTTP 200 的 text/plain 格式文本. 默認值: pong.
request_terminate_timeout = 0
#設置單個請求的超時中止時間. 該選項可能會對php.ini設置中的』max_execution_time』因為某些特殊原因沒有中止運行的腳本有用. 設置為 』0′ 表示 『Off』.當經常出現502錯誤時可以嘗試更改此選項。
request_slowlog_timeout = 10s
#當一個請求該設置的超時時間後,就會將對應的PHP調用堆棧信息完整寫入到慢日誌中. 設置為 』0′ 表示 『Off』
slowlog = log/$pool.log.slow
#慢請求的記錄日誌,配合request_slowlog_timeout使用
rlimit_files = 1024
#設置文件打開描述符的rlimit限制. 默認值: 系統定義值默認可打開句柄是1024,可使用 ulimit -n查看,ulimit -n 2048修改。
rlimit_core = 0
#設置核心rlimit最大限制值. 可用值: 『unlimited』 、0或者正整數. 默認值: 系統定義值.
chroot =
#啟動時的Chroot目錄. 所定義的目錄需要是絕對路徑. 如果沒有設置, 則chroot不被使用.
chdir =
#設置啟動目錄,啟動時會自動Chdir到該目錄. 所定義的目錄需要是絕對路徑. 默認值: 當前目錄,或者/目錄(chroot時)
catch_workers_output = yes
#重定向運行過程中的stdout和stderr到主要的錯誤日誌文件中. 如果沒有設置, stdout 和 stderr 將會根據FastCGI的規則被重定向到 /dev/null . 默認值: 空.
根據以上配置的解析,在php-fpm.conf文件中添加如下配置:
pm.max_children = 100
pm.start_servers = 30
pm.min_spare_servers = 20
pm.max_spare_servers = 100
以觀後效。
另附豆瓣技術貼:https://www.douban.com/note/315222037/
1、php-fpm優化參數介紹
他們分別是:pm、pm.max_children、pm.start_servers、pm.min_spare_servers、pm.max_spare_servers。
pm:表示使用那種方式,有兩個值可以選擇,就是static(靜態)或者dynamic(動態)。
在更老一些的版本中,dynamic被稱作apache-like。這個要注意看配置文件的說明。
下面4個參數的意思分別為:
pm.max_children:靜態方式下開啟的php-fpm進程數量
pm.start_servers:動態方式下的起始php-fpm進程數量
pm.min_spare_servers:動態方式下的最小php-fpm進程數
pm.max_spare_servers:動態方式下的最大php-fpm進程數量
區別:
如果dm設置為 static,那麼其實只有pm.max_children這個參數生效。系統會開啟設置數量的php-fpm進程。
如果dm設置為 dynamic,那麼pm.max_children參數失效,後面3個參數生效。
系統會在php-fpm運行開始 的時候啟動pm.start_servers個php-fpm進程,
然後根據系統的需求動態在pm.min_spare_servers和pm.max_spare_servers之間調整php-fpm進程數
2、伺服器具體配置
對於我們的伺服器,選擇哪種執行方式比較好呢?事實上,跟Apache一樣,運行的PHP程序在執行完成後,或多或少會有內存泄露的問題。
這也是為什麼開始的時候一個php-fpm進程只佔用3M左右內存,運行一段時間後就會上升到20-30M的原因了。
對於內存大的伺服器(比如8G以上)來說,指定靜態的max_children實際上更為妥當,因為這樣不需要進行額外的進程數目控制,會提高效率。
因為頻繁開關php-fpm進程也會有時滯,所以內存夠大的情況下開靜態效果會更好。數量也可以根據 內存/30M 得到,比如8GB內存可以設置為100,
那麼php-fpm耗費的內存就能控制在 2G-3G的樣子。如果內存稍微小點,比如1G,那麼指定靜態的進程數量更加有利於伺服器的穩定。
這樣可以保證php-fpm只獲取夠用的內存,將不多的內存分配給其他應用去使用,會使系統的運行更加暢通。
對於小內存的伺服器來說,比如256M內存的VPS,即使按照一個20M的內存量來算,10個php-cgi進程就將耗掉200M內存,那系統的崩潰就應該很正常了。
因此應該盡量地控制php-fpm進程的數量,大體明確其他應用佔用的內存後,給它指定一個靜態的小數量,會讓系統更加平穩一些。或者使用動態方式,
因為動態方式會結束掉多餘的進程,可以回收釋放一些內存,所以推薦在內存較少的伺服器或VPS上使用。具體最大數量根據 內存/20M 得到。
比如說512M的VPS,建議pm.max_spare_servers設置為20。至於pm.min_spare_servers,則建議根據伺服器的負載情況來設置,比如伺服器上只是部署php環境的話,比較合適的值在5~10之間。
本伺服器配置
1、伺服器基本信息:
硬碟:數據盤30G、系統盤20G
內存:1.5G
CPU:雙核
系統:CentOS 6.3 64位
帶寬:獨享2M
2、部署的應用
Git、SVN、Apache、Tomcat、PHP、Nginx、mysql、JDK
3、優化後的參數
pm = dynamic
pm.start_servers = 5
pm.min_spare_servers = 2
pm.max_spare_servers = 8
⑷ PHP-FPM詳解
PHP-FPM是PHP FastCGI進程管理器,專為管理PHP進程池設計,用於接收web伺服器請求。
第一部分,為什麼出現PHP-FPM?PHP-FPM的誕生源自PHP-FastCGI的需求。為有效管理PHP-FastCGI而出現的程序。
第二部分,了解PHP-FastCGI。它只是一個解析PHP請求並返回結果的CGI程序,並不負責管理進程。
第三部分,為何不稱為PHP-CGI?在PHP-FastCGI之前,存在PHP-CGI,但其執行效率低下,最終被PHP-FastCGI取代。
第四部分,解釋FastCGI與CGI的區別。在FastCGI時代,當web伺服器(如nginx)接收到請求並識別為動態PHP請求時,會將其轉給PHP處理。在CGI模式下,每次請求時都需要讀取php.ini配置,初始化執行環境,耗時且重復。
第五部分,FastCGI的效率提升。FastCGI允許一次啟動一個主進程(master),讀取一次配置,然後啟動多個工作進程(worker)。當請求來臨時,master將請求傳遞給worker,避免了重復的初始化工作。
第六部分,PHP-FPM的工作原理。PHP-FPM創建一個主進程來控制何時以及如何將HTTP請求轉發給一個或多個子進程處理。主進程還負責管理進程的創建與銷毀,以適應Web應用流量的變化。
安裝部分,PHP在5.3.3之後將PHP-FPM整合到核心代碼中,無需單獨下載安裝。只需在編譯PHP源碼時添加--enable-fpm即可啟用PHP-FPM支持。
全局配置方面,CentOS中PHP-FPM的主配置文件為/etc/php7/php-fpm.conf,配置內容通常包括進程池定義。
在CentOS中,PHP-FPM主配置文件頂部引入了進程池定義文件,通常使用www.conf作為默認配置文件。進行必要的編輯保存後,重啟PHP-FPM主進程。
PHP-FPM進程池的詳細配置請參考php.net/manual/install文檔。
針對Company開發環境的配置,提供測試環境與生產環境的具體配置示例。以nginx為例,說明如何轉發請求給PHP-FPM。
最後,針對PHPer進階時遇到的問題,提供了一系列資料,涵蓋分布式架構、高可擴展性、高性能、高並發、伺服器性能調優、TP6、Laravel、YII2、Redis、Swoole、Swoft、Kafka、Mysql優化、shell腳本、Docker、微服務、Nginx等高級進階干貨,需要的讀者可以免費獲取。