php-fpm優化
前言:
最近在騰訊雲買了臺學生機打算搭個博客玩玩,由於空間還在備案中,於是就想著先把環境(LNMP+phpmyadmin+wordpress)部署好,環境很順利,但晚上重新連上雲服務器敲命令時那延時真是叫一個痛苦啊,思來想去覺得八成是內存被耗盡了,於是開始排查優化之旅
查看內存使用情況:
# free -m total used free shared buffers cached Mem: 996 933 63 0 74 268 -/+ buffers/cache: 284 712 Swap: 0 0 0
果然,內存幾乎被吃盡,看看哪些亂來的進程吃了我的內存
# ps -A --sort -rss -o comm,pmem,pcpu |uniq -c |head -10 1 COMMAND %MEM %CPU 1 mysqld 9.1 0.0 1 php-fpm 3.6 0.9 1 php-fpm 3.4 0.9 1 php-fpm 3.4 0.8 1 php-fpm 3.4 0.9 2 php-fpm 3.4 0.8 2 php-fpm 3.4 0.6 1 php-fpm 3.4 0.8 3 php-fpm 3.4 0.9 # ps aux | grep php-fpm |wc -l 22
除去以root身份運行的作為管理各個php-fpm進程的 master 進程與grep進程,php-fpm竟然有多達20個占用3.4M的php-fpm進程
先把mysqld放一邊,我們發現很大一部分的內存都被 php-fpm 進程吞了,看來有必要對 php-fpm 做個優化了
優化前,我們有必要了解一下 php-fpm 這個組件,以及php-fpm在 nginx 環境下必不可缺的原因
php-fpm:php-FastCGI Process Manager
我們知道apache與php結合的方式有3種: (找機會對這3種方式做個詳細介紹)
1.配置apache,將php解釋器作為cgi腳本
2.將php直接裝載進apache模塊
3.使用fastcgi
[註]apache默認使用第二種方式
但是,Nginx不支持對外部程序的直接調用或者解析,並且Nginx默認就不支持cgi模式,所以通常Nginx都是使用 fastcgi 的方式與php結合
簡單介紹fast-cgi
fast-cgi在安裝後一旦啟用將 監聽在TCP的某個套接字 上,通常表現為 127.0.0.1:9000 ,於是現在客戶端瀏覽器訪問一個動態網頁(如index.php)時發生的行為:nginx將用戶的http請求接進來,發現用戶請求的是一個php腳本,於是交給fastcgi分析處理,處理完畢後(經過php解釋器解釋與從mysql中取數據)將結果回送給nginx,nginx最後將靜態內容返回給客戶端,所以我們能感受到fast-cgi的一大好處是:將動態腳本的解釋過程從nginx抽出,使得nginx只需專註於與客戶端交互靜態資源,而將動態php腳本分析統統扔給fast-cgi,這樣一來能將動態腳本分析過程從nginx進程中解放出來從而增強nginx的並發能力,二來當php掛了不至於讓nginx一起掛了
介紹完fast-cgi的重要性,只是希望告訴大家雖然現在php-fpm占用了不少的內存空間,但可不能將其打入冷宮,隨隨便便把它們kill或者將php-fpm服務停掉了(這樣你的網站將無法訪問),下面先介紹一下php-fpm配置文件一些重要參數的含義,然後再針對性得做些優化措施
由於我是rpm安裝的php-fpm,所以得先找找相關配置文件
# rpm -qc php-fpm /etc/logrotate.d/php-fpm /etc/php-fpm.conf /etc/php-fpm.d/www.conf /etc/sysconfig/php-fpm
根據上方ps的提示,我們這裏應當重點優化php-fpm與www相關的參數
# cat /etc/php-fpm.d/www.conf | grep -v "^;" [www] listen = 127.0.0.1:9000 listen.allowed_clients = 127.0.0.1 user = apache group = apache pm = dynamic # pm模式 pm.max_children = 20 # 最大可創建的子進程的數量 pm.start_servers = 10 # 隨著php-fpm-master一起啟動時創建的子進程數目 pm.min_spare_servers = 5 # 服務器空閑時最小php-fpm進程數量 pm.max_spare_servers = 20 # 服務器空閑時最大php-fpm進程數量 slowlog = /var/log/php-fpm/www-slow.log # 慢查詢日誌存放路徑 php_admin_value[error_log] = /var/log/php-fpm/www-error.log php_admin_flag[log_errors] = on php_value[session.save_handler] = files php_value[session.save_path] = /var/lib/php/session
pm的三種模式:
static 表示我們創建固定數量的php-fpm子進程,所以只有 pm.max_children=20 參數生效。啟動php-fpm時會一次性全部啟動21(1個主+20個子)個進程
dynamic 表示啟動進程是動態分配的,子進程的數量隨著請求量的變化以及上述一些參數限制動態變化著
ondemand 該模式下按需分配、銷毀子進程,子進程捆綁了空閑計時器 pm.process_idle_timeout 一旦空閑時間計時器超時就將子進程kill
所以,現在結合php-fpm的默認配置就能解釋:上面用ps輸出發現系統跑著20個php-fpm子進程的原因了
我這個小小站,根據 pm.start_servers=10 剛啟動php-fpm時會產生1個主進程以及10個子進程,當這10個子進程對用戶的大量動態請求忙不過來時,將不斷啟動新的php-fpm子進程以滿足需要,但根據 pm.max_children=20 系統最多只會產生20個子進程,而由於 pm.max_spare_servers=20 假設某時間段內,網站一直沒人訪問,但卻仍需維護著20個子進程,對於像我這種小小站而言,子進程的空閑數量過多了,所以這也是一個優化點,嘮叨這麽多怕大家反而暈頭轉向的,不妨瞅瞅我隨手畫的圖加深理解
大家有了這些知識做鋪墊,想必php-fpm的優化技巧不用我說也能猜到一二了吧(如果看官依然懵逼那只能說“看來我這水平還不夠”)
優化方案1:pm模式使用dynamic
配置要點
# vim /etc/php-fpm.d/www.conf pm = dynamic pm.max_children = 8 pm.start_servers = 3 pm.min_spare_servers = 3 pm.max_spare_servers = 5
重啟 php-fpm 並查看內存占用情況
# service php-fpm restart 停止 php-fpm: [確定] 正在啟動 php-fpm: [確定] # free -m total used free shared buffers cached Mem: 996 410 585 0 90 111 -/+ buffers/cache: 209 787 Swap: 0 0 0
現在內存使用量的確舒服多了,順便看看初始時啟用的子進程數目
# ps aux | grep php-fpm | wc -l 5
5-2=3符合我們上方 pm.start_servers=3 的修改
此時nginx尚未配置頁面緩存,所以可以不斷刷新站點來測試(讓僅有的3個fpm進程忙不過來)看看內存占用情況,下面貼出測試後的現象
# free -m total used free shared buffers cached Mem: 996 517 478 0 90 112 -/+ buffers/cache: 314 681 Swap: 0 0 0
# ps aux | grep php-fpm | wc -l 7
系統當前運行的php-fpm子進程個數也符合我們設置的 pm.max_spare_servers=5 (最大空閑進程數)
優化方案2:pm模式使用 ondemand
配置要點
# vim /etc/php-fpm.d/www.conf pm = ondemand
網站在某刻有大量請求湧入時,內存占用情況
# free -m total used free shared buffers cached Mem: 996 765 231 0 90 112 -/+ buffers/cache: 561 435 Swap: 0 0 0
網站平穩時(沒人訪問)系統只跑了個 php-fpm master 進程(因為子進程由於閑置時間過長而被kill掉了)所以此時內存占用也就大大降低啦
# ps aux | grep php-fpm root 29549 0.0 0.6 317072 6148 ? Ss 10:16 0:00 php-fpm: master process (/etc/php-fpm.conf) root 30099 0.0 0.0 103272 884 pts/0 S+ 10:28 0:00 grep php-fpm # free -m total used free shared buffers cached Mem: 996 414 582 0 91 115 -/+ buffers/cache: 207 789 Swap: 0 0 0
看到這裏,想必各位看官也能自己總結出php-fpm各模式下的優缺點以及php-fpm的優化技巧了吧
本文出自 “cfcgo” 博客,請務必保留此出處http://cfcgo.blog.51cto.com/12425690/1922796
php-fpm優化