最近發現部落格的記憶體老是隔三差五地被「吃掉」了,登入後台後偶爾會出卡頓的情況,一開始懷疑是Swap不夠導致的,於是給VPS主機增加了幾個G的Swap,觀察了一段時間後發現再大的Swap也被慢慢地「吃掉」了!

很顯然是PHP某些服務一直在佔用著VPS的內存沒有釋放,導致物理內存耗儘後調用了Swap,顯然Swap沒有物理內存運行的效率高,於是就出現了進程卡死的情況了。考慮到挖站否現在用的Wordpress用的主題與外掛過多,出現這樣的情況也是正常。

LNMP架構中PHP是運行在FastCGI模式下,按照官方的說法,php-cgi會在每個請求結束的時候會回收腳本使用的全部內存,但是並不會釋放給操作系統,而是繼續持有以應對下一次PHP請求。而php-fpm是FastCGI進程管理器,用來控制php的記憶體和進程等。

Linux的php-fpm優化心得-php-fpm行程佔用記憶體大和不釋放記憶體

所以,解決的方法就是透過php-fpm來優化總的進程數和單一進程佔用的內存,從而解決php-fpm進程佔用內存大和不釋放內存的問題。更多的Linux伺服器最佳化方法以及建置站心得,還有:

  1. Linux Crontab指令定時任務基本語法與操作教學-VPS/伺服器自動化
  2. 阿里雲日本VPS主機速度效能評測-日本軟銀SoftBank香港NTT線路
  3. DNS網域名稱解析啟用DNSSEC防止DNS劫持-Google Cloud DNS設定DNSSEC

PS:2018年12月14日更新,如果你的VPS主機的記憶體和效能不是很好的話,這時最好是啟用快取可以大幅節省資源消耗:WordPress開啟Nginx fastcgi_cache快取加速方法-Nginx設定實例。

PS:2019年9月29日更新,由於Google主導開發的伺服器優化神器ngx_pagespeed,整合了圖片延遲載入、自適應webp、JS和CSS優化、圖片優化等一整套優化工具:PageSpeed伺服器優化神器-Nginx部署ngx_pagespeed模組和加速效果體驗。

一、分析判斷php-fpm記憶體佔用情況

如果你發現VPS主機出現了卡頓的狀況,先查看一下記憶體的佔用狀況,常用的指令就是Top、Glances、Free等,不了解這些指令的朋友可以先看看挖站否做的專題:Linux系統監控指令整理匯總-掌握CPU,記憶體,磁碟IO等找出效能瓶頸。

使用Glances指令,再按下m,就可以查看到目前VPS主機進程記憶體佔用情況了,依照佔用記憶體由多到少排序(或是使用Top指令,按下M,效果是一樣的)。如下圖(點擊可放大):

3.2  減少php-fpm進程數

如果你的VPS主機的記憶體被佔用耗盡,可以檢查一下你的php-fpm進程數,依照php-fpm進程數=記憶體/2/30來計算,1GB記憶體適合的php-fpm進程數為10- 20之間,具體還得根據你的PHP加載的附加元件有關係。

3.3  php-fpm配置範例

這裡以1GB記憶體的VPS配置php-fpm為演示,實際操作來看設定數值還得根據伺服器本身的效能、PHP等綜合考慮。

pm = dynamic #dynamic和ondemand适合小内存。
pm.max_children = 15 #static模式下生效,dynamic不生效。
pm.start_servers = 8 #dynamic模式下开机的进程数量。
pm.min_spare_servers = 6 #dynamic模式下最小php-fpm进程数量。
pm.max_spare_servers = 15 #dynamic模式下最大php-fpm进程数量。

四、解決php-fpm進程不釋放記憶體問題

上面透過減少php-fpm進程總數來達到減少php-fpm記憶體佔用的問題,實際使用過程中發現php-fpm進程還存長期佔用記憶體而不釋放的問題。解決的方法就是減少pm.max_requests數。

最大請求數max_requests,也就是當一個 PHP-CGI 進程處理的請求數累積到 max_requests 個後,自動重啟該進程,這樣達到了釋放記憶體的目的了。以1GB記憶體的VPS主機設定為例(如果你設定的數值沒有達到釋放記憶體可以繼續調低):

pm.max_requests = 500 

當php-fpm進程達到了pm.max_requests設定的數值後,就會重新啟動該進程,從而釋放記憶體。下圖是我測試後的效果,可以看出php-fpm進程被強制結束並釋放了記憶體。

五、總結

對於大內存以及對並發和可用性要求的話,建議使用static管理模式+最大的pm.max_children。如果是小型記憶體的伺服器,建議使用dynamic或ondemand模式,同時降低pm.start_servers和pm.max_spare_servers進程數。

為什麼我調整了參數沒有達到應有的效果?根據wzfou.com的經驗,php-fpm設定檔參數不能一概而論,必須要結合伺服器本身的效能、WEB動態內容以及對可用性的要求來進行調整,記憶體長期佔用最好是再檢查一下是否有記憶體外洩。

2019年10月9日更新,如果你的php-fpm參數調整得太小,有可能出現502錯誤,解決方法:解決WordPress後台編輯保存選單出現502錯誤。

發表評論