## 參考來源: https://www.cnblogs.com/qq78292959/p/4034359.html
php-fpm的安裝很簡單,參見[PHP(PHP-FPM)手動編譯安裝](http://blog.csdn.net/dc_726/article/details/9519619)。下面主要討論下如何提高Nginx+Php-fpm的性能。
**1.Unix域Socket通信**
之前簡單介紹過Unix Domain Socket這種通信方式,參見:[Nginx+PHP-FPM的域Socket配置方法](http://blog.csdn.net/dc_726/article/details/9336193)
Unix域Socket因為不走網絡,的確可以提高Nginx和php-fpm通信的性能,但在高并發時會不穩定。
Nginx會頻繁報錯:
? ? ?connect() to unix:/dev/shm/php-fcgi.sock failed (11: Resource temporarily unavailable) while connecting to upstream
可以通過下面兩種方式提高穩定性:
1)調高nginx和php-fpm中的backlog
? ? ?配置方法為:在nginx配置文件中這個域名的server下,在listen 80后面添加default backlog=1024。
? ? ?同時配置php-fpm.conf中的listen.backlog為1024,默認為128。
2)增加sock文件和php-fpm實例數
? ? ?再新建一個sock文件,在Nginx中通過upstream模塊將請求負載均衡到兩個sock文件背后的兩套php-fpm實例上。
* * *
**2.php-fpm參數調優**
**2.1進程數**
php-fpm初始/空閑/最大worker進程數
? ? ?pm.max\_children = 300
? ? ?pm.start\_servers = 20
? ? ?pm.min\_spare\_servers = 5
? ? ?pm.max\_spare\_servers = 35
**2.2最大處理請求數**
最大處理請求數是指一個php-fpm的worker進程在處理多少個請求后就終止掉,master進程會重新respawn一個新的。
這個配置的主要目的是避免php解釋器或程序引用的第三方庫造成的內存泄露。
? ? ?pm.max\_requests = 10240
**2.3最長執行時間**
最大執行時間在php.ini和php-fpm.conf里都可以配置,配置項分別為max\_execution\_time和request\_terminate\_timeout。
其作用及其影響參見:[Nginx中502和504錯誤詳解](http://blog.csdn.net/dc_726/article/details/11950189)
* * *
**3.php-fpm的高CPU使用率排查方法**
**3.1CPU使用率監控方法**
1)top命令
直接執行top命令后,輸入1就可以看到各個核心的CPU使用率。而且通過top -d 0.1可以縮短采樣時間。
下面的sar貌似最短只能是1秒。
2)sar命令
sar和iostat命令的安裝:
?????sysstat.x86\_64 : The sar and iostat system monitoring commands
? ? ?yum install -y?sysstat.x86\_64
執行sar -P ALL 1 100。-P ALL表示監控所有核心,1表示每1秒采集,100表示采集100次。
輸出結果如下:
`CPU?????%user?????%nice???%system???%iowait????%steal?????%idle`
`all?????85.54??????0.00??????5.69??????0.00??????0.00??????8.76`
`0?????74.75??????0.00?????25.25??????0.00??????0.00??????0.00`
`1?????98.00??????0.00??????2.00??????0.00??????0.00??????0.00`
`2?????89.22??????0.00??????3.92??????0.00??????0.00??????6.86`
`3?????91.00??????0.00??????2.00??????0.00??????0.00??????7.00`
`4?????75.00??????0.00??????9.00??????0.00??????0.00?????16.00`
`5?????94.95??????0.00??????5.05??????0.00??????0.00??????0.00`
`6?????95.00??????0.00??????4.00??????0.00??????0.00??????1.00`
`7?????87.88??????0.00??????4.04??????0.00??????0.00??????8.08`
`8?????93.94??????0.00??????3.03??????0.00??????0.00??????3.03`
`9?????88.00??????0.00??????3.00??????0.00??????0.00??????9.00`
`10?????89.11??????0.00??????2.97??????0.00??????0.00??????7.92`
`11?????82.35??????0.00??????3.92??????0.00??????0.00?????13.73`
`12?????73.27??????0.00??????7.92??????0.00??????0.00?????18.81`
`13?????81.44??????0.00??????4.12??????0.00??????0.00?????14.43`
`14?????77.23??????0.00??????6.93??????0.00??????0.00?????15.84`
`15?????78.79??????0.00??????4.04??????0.00??????0.00?????17.17`
**3.2開啟慢日志**
配置輸出php-fpm慢日志,閥值為2秒:
> request\_slowlog\_timeout = 2
> slowlog = log/$pool.log.slow
利用sort/uniq命令分析匯總php-fpm慢日志:
`[root@b28-12?log]#?grep?-v?"^$"?www.log.slow.tmp?|?cut?-d?"?"?-f?3,2?|?sort?|?uniq?-c?|?sort?-k1,1nr?|?head?-n?50`
`5181?run()?/www/test.net/framework/web/filters/CFilter.php:41`
`5156?filter()?/www/test.net/framework/web/filters/CFilterChain.php:131`
`2670?=?/www/test.net/index.php`
`2636?run()?/www/test.net/application/controllers/survey/index.php:665`
`2630?action()?/www/test.net/application/controllers/survey/index.php:18`
`2625?run()?/www/test.net/framework/web/actions/CAction.php:75`
`2605?runWithParams()?/www/test.net/framework/web/CController.php:309`
`2604?runAction()?/www/test.net/framework/web/filters/CFilterChain.php:134`
`2538?run()?/www/test.net/framework/web/CController.php:292`
`2484?runActionWithFilters()?/www/test.net/framework/web/CController.php:266`
`2251?run()?/www/test.net/framework/web/CWebApplication.php:276`
`1799?translate()?/www/test.net/application/libraries/Limesurvey_lang.php:118`
`1786?load_tables()?/www/test.net/application/third_party/php-gettext/gettext.php:254`
`1447?runController()?/www/test.net/framework/web/CWebApplication.php:135`
參數解釋:
?????sort:? 對單詞進行排序
?????uniq -c:? 顯示唯一的行,并在每行行首加上本行在文件中出現的次數
?????sort -k1,1nr:? 按照第一個字段,數值排序,且為逆序
?????head -10:? 取前10行數據
**3.3用strace跟蹤進程**
1)利用nohup將strace轉為后臺執行,直到attach上的php-fpm進程死掉為止:
> nohup strace -T -p 13167 > 13167-strace.log &
參數說明:
> **\-c 統計每一系統調用的所執行的時間,次數和出錯的次數等.**
>
> \-d 輸出strace關于標準錯誤的調試信息.
>
> **\-f 跟蹤由fork調用所產生的子進程.**
>
> \-o filename,則所有進程的跟蹤結果輸出到相應的filename
>
> \-F 嘗試跟蹤vfork調用.在-f時,vfork不被跟蹤.
>
> \-h 輸出簡要的幫助信息.
>
> \-i 輸出系統調用的入口指針.
>
> \-q 禁止輸出關于脫離的消息.
>
> \-r 打印出相對時間關于,,每一個系統調用.
>
> \-t 在輸出中的每一行前加上時間信息.
>
> \-tt 在輸出中的每一行前加上時間信息,微秒級.
>
> \-ttt 微秒級輸出,以秒了表示時間.
>
> **\-T 顯示每一調用所耗的時間.**
>
> \-v 輸出所有的系統調用.一些調用關于環境變量,狀態,輸入輸出等調用由于使用頻繁,默認不輸出.
>
> \-V 輸出strace的版本信息.
>
> \-x 以十六進制形式輸出非標準字符串
>
> \-xx 所有字符串以十六進制形式輸出.
>
> \-a column
>
> 設置返回值的輸出位置.默認為40.
>
> \-e execve 只記錄 execve 這類系統調用
>
> **\-p 主進程號**
2)也可以用利用-c參數讓strace幫助匯總,非常方便非常強大!
`[root@b28-12?log]#?strace?-cp?9907`
`Process?9907?attached?-?interrupt?to?quit`
`Process?9907?detached`
`%?time?????seconds??usecs/call?????calls????errors?syscall`
`------?-----------?-----------?---------?---------?----------------`
`56.61????0.016612???????????5??????3121???????????read`
`11.11????0.003259???????????1??????2517???????715?stat`
`8.04????0.002358???????????7???????349???????????brk`
`6.02????0.001767???????????1??????1315???????????poll`
`4.28????0.001255???????????6???????228???????????recvfrom`
`2.71????0.000796???????????1???????671???????????open`
`2.54????0.000745???????????0??????2453???????????fcntl`
`2.37????0.000696???????????1??????1141???????????write`
`1.69????0.000497???????????1???????593????????13?access`
`1.37????0.000403???????????0??????1816???????????lseek`
`0.89????0.000262???????????1???????451????????22?sendto`
`0.56????0.000163???????????1???????276???????208?lstat`
`0.49????0.000145???????????0???????384???????????getcwd`
`0.31????0.000090???????????0??????1222???????????fstat`
`0.28????0.000082???????????0???????173???????????munmap`
`0.26????0.000077???????????0???????174???????????mmap`
`0.24????0.000069???????????2????????41???????????socket`
`0.23????0.000068???????????0???????725???????????close`
`0.00????0.000000???????????0????????13???????????rt_sigaction`
`0.00????0.000000???????????0????????13???????????rt_sigprocmask`
`0.00????0.000000???????????0?????????1???????????rt_sigreturn`
`0.00????0.000000???????????0????????78???????????setitimer`
`0.00????0.000000???????????0????????26????????26?connect`
`0.00????0.000000???????????0????????15?????????2?accept`
`0.00????0.000000???????????0????????39???????????recvmsg`
`0.00????0.000000???????????0????????26???????????shutdown`
`0.00????0.000000???????????0????????13???????????bind`
`0.00????0.000000???????????0????????13???????????getsockname`
`0.00????0.000000???????????0????????65???????????setsockopt`
`0.00????0.000000???????????0????????13???????????getsockopt`
`0.00????0.000000???????????0?????????8???????????getdents`
`0.00????0.000000???????????0????????26???????????chdir`
`0.00????0.000000???????????0?????????1???????????futex`
`------?-----------?-----------?---------?---------?----------------`
`100.00????0.029344?????????????????18000???????986?total`
ps:可以使用strace學習php解釋器的解釋執行過程
**3.4加速PHP解釋執行**
如果自己的程序的確沒有問題,只是執行了太多操作,沒法再做優化了。則考慮使用APC或xcache等PHP加速器來減少CPU解釋php文件的耗時。
這些PHP加速器在php文件第一次解釋時會生成中間代碼opcode,所以之后的執行會快很多,并且減少了一些CPU的運算。下面以xcache為例,
看下如何安裝和配置。
安裝xcache命令如下,./configure的參數好多不知道是做什么用的,官網上也沒說明,所以只開啟--enable-xcache了:
? ? ?tar zxvf xcache-3.0.3.tar.gz
? ? ?/usr/local/php/bin/phpize
? ? ?./configure?--with-php-config=/usr/local/php/bin/php-config --enable-xcache
? ? ?make
? ? ?make install
php.ini中配置如下,最重要的是標紅的兩個參數,一般推薦xcache.size根據php文件多少來定,xcache.count與CPU核心數相同:
> \[xcache.admin\]
>
> xcache.admin.enable\_auth = Off
>
> xcache.admin.user = "xcache"
>
> xcache.admin.pass = ""
>
> \[xcache\]
>
> xcache.shm\_scheme ="mmap"
>
> **xcache.size=1024M**
>
> **xcache.count =16**
>
> xcache.slots =8K
>
> xcache.ttl=0
>
> xcache.gc\_interval =0
>
> xcache.var\_size=16M
>
> xcache.var\_count =1
>
> xcache.var\_slots =8K
>
> xcache.var\_ttl=0
>
> xcache.var\_maxttl=0
>
> xcache.var\_gc\_interval =300
>
> xcache.test =Off
>
> xcache.readonly\_protection = Off
>
> ;xcache.readonly\_protection = On
>
> xcache.mmap\_path ="/dev/zero"
>
> ;xcache.mmap\_path ="/tmp/xcache"
>
> xcache.coredump\_directory =""
>
> xcache.cacher =On
>
> xcache.stat=On
>
> xcache.optimizer =Off
>
> \[xcache.coverager\]
>
> ;;xcache.coverager =On
>
> ;;xcache.coveragedump\_directory =""
常見問題是啟動php-fpm時會報錯:
?????Cannot open or create file set by xcache.mmap\_path, check the path permission or check xcache.size/var\_size against system limitation
這是因為/tmp/xcache是一個文件,而不能創建成目錄。
重啟php-fpm服務后,用top命令觀察會發現每個worker進程的VIRT(包含了swap區)都是xcache.size大小,但REQ變得很小了。
使用上面的配置在使CPU使用率的峰值時間變短了,但峰值時還是所有核心都會達到90%以上,不知道是不是哪里沒有配置對。
另外高并發時,/dev/zero這種配置方式經常會導致Nginx 502錯誤。/tmp/xcache和開啟readonly\_protection則很穩定。
* * *
**4.php程序性能監控**
常用的方法就是開啟xdebug的性能監控功能,將xdebug輸出結果通過WinCacheGrind軟件分析。
xdebug的安裝和配合IDE調試的方法參見:[Vim+XDebug調試PHP](http://blog.csdn.net/dc_726/article/details/8809696)
php.ini中配置的這幾項是輸出性能信息的:
> xdebug.auto\_trace = on
> xdebug.auto\_profile = on
> xdebug.collect\_params = on
> xdebug.collect\_return = on
> xdebug.profiler\_enable = on
> xdebug.trace\_output\_dir = "/tmp"
> xdebug.profiler\_output\_dir ="/tmp"
這樣XDebug會輸出所有執行php函數的性能數據,但產生的文件也會比較大。可以關閉一些選項如collect\_params、collect\_return,
來減少輸出的數據量。或者關閉自動輸出,通過在想要監控的函數首尾調用xdebug函數來監控指定的函數。
輸出的文件名類似cachegrind.out.1277560600和trace.3495983249.txt,可以拿到Windows平臺下用WinCacheGrind進行圖形化分析。
WinCacheGrind使用方法網上有很多介紹,這里就不詳細說明了。
- 常見功能
- 第三方授權登錄
- 郵件發送
- 簡易聊天室
- 獲取各國匯率
- PHP獲取服務器硬件指標
- 數據上報之
- web開發
- 開發規范
- 前端
- 踩坑
- 將footer固定在底部
- bootstrap
- Metronic
- 用到的jquery插件
- bootstrap-hover-dropdown
- jquery.slimscroll
- jquery.blockui
- bootstrap-switch
- js.cookie
- moment
- bootstrap-daterangepicker
- morris
- raphael
- jquery.waypoints
- jquery.counterup
- select2
- 取值和設置默認值
- vue
- axios
- 瀏覽器
- 谷歌瀏覽器
- 谷歌插件
- layui
- layui-表格
- layui-表單
- layui-彈窗
- layui-分頁
- 后端
- 操作系統
- linux
- 用戶管理
- 文件管理
- 目錄管理
- 壓縮和解壓縮
- 進程查看
- 端口查看
- 開機自啟動服務
- 定時任務
- shell腳本
- 殺掉運行超過指定時長指定服務的進程
- 獲取服務器使用狀態
- bash-shell連接socket
- 自定義快捷命令
- centos-踩坑
- 防火墻
- 軟件
- yum
- vim
- screen
- window
- 語言
- PHP
- 配置優化
- 框架
- thinkphp5.1+
- think命令行
- laravel6.+
- 維護模式
- 根據環境讀取不同配置
- laravel6.+采坑
- laravel坑位
- 數據庫事務
- 任務調度
- 文件權限問題
- 增強框架
- larvel:elastic-search
- 圖形驗證碼
- laravel獲取ip
- 函數
- strtotime
- 正則匹配
- 類
- 接口類與抽象類
- 類相關的關鍵字 - abstract
- 類相關的關鍵字 - interface
- PHP有關類的調用方式"->"與"::"的區別
- 擴展
- 問題歸納
- json_encode和json_decode
- 字符串的運算
- curl
- 優化php效率
- 數組相加合并與array_merge
- 時區轉換
- 不常用特性
- php反射
- 包管理器-composer
- GuzzleHttp
- Python
- Go
- 數據庫
- Redis
- 安裝
- 本地化-數據備份
- php-redis操作
- Mysql
- mysql-命令集合
- 設置終端可訪問
- 數據庫設計
- 用戶基礎信息表
- 踩坑集合
- mysql-2002
- mysql-2054
- 優化策略
- mysql-密碼驗證插件
- 一些牛逼的sql查詢
- topN
- 無限級分類
- Memcache
- MongoDb
- 安裝mongo-server
- 安裝php-mongodb擴展
- 在laravel中使用mongoDB
- 客戶端軟件
- Hbase
- Elasticsearch
- elastic-search
- restfulApi操作es
- web服務器
- 1.nginx
- 配置語法規則
- 配置詳解
- rewrite規則
- request_filename
- 2.apache
- 功能設計
- 加密解密
- Base64
- 對亞馬遜SKU加密
- 兼職項目中的加解密
- 騰訊外包時的加密
- 接口設計
- 接口限流設計
- 分庫分表
- 遍歷展示文件目錄結構
- 時區換算
- 文件切割
- 解析xml字符串
- 項目
- 博客后臺管理
- 亞馬遜廣告API
- 官方指引文檔
- 開發人員中心
- 應用商店
- 第三方庫
- 申請API郵件記錄
- 亞馬遜MWS
- 付款報告
- 亂碼
- 亞馬遜管理庫存報告
- 報告
- 商品
- 入庫
- 履行
- 出庫
- 財務
- 訂單
- 異步任務處理
- 集群如何同步代碼
- 基本開發流程
- 文檔管理
- showdoc
- 運行環境
- 開發環境
- vagrant
- windows上配置安裝
- vagrant安裝插件緩慢
- 更換ssh默認端口映射
- 設置x-shell密碼登錄
- 使用市場的box-homestead
- homestead-7: Box 'lc/homestead'
- 常見問題
- 虛擬環境reboot
- 突然無法使用
- phpStudy
- wamp
- 壓測性能
- VPN
- vultr
- 凌空圖床
- 寶塔
- 自動化部署
- 版本管理軟件鉤子
- 線上環境-LNMP
- centos7
- nginx
- mysql
- mysql開機自啟
- mysql-更換默認端口
- datetime字段類型默認值
- php
- php擴展安裝
- redis
- swoole
- gd
- BCMath
- igbinary
- zstd
- 包管理器:composer
- 優化性能
- nodejs
- 更新gcc版本
- 版本控制
- git
- 常用命令
- gitlab
- 版本管理規范
- 使用阿里云創建遠程倉庫
- git自動化部署
- svn
- 忽略指定文件
- 拉取代碼
- 自動化運維
- jekins
- 容器
- 集群
- 架構設計
- 設計原則
- 閱讀參考
- 代碼規劃
- 架構實戰
- 服務治理
- 權限控制設計
- 具體設計
- 計劃
- 疑問知識點
- 讀書筆記
- 高性能Mysql
- TCP-IP詳解-卷一:協議
- 思考
- php如何實現并發執行
- 對接調用設計
- 如何在瀏覽器上實現插件
- 如何設計一個app結合業務告警
- mysql的where查詢沒有用到索引
- 為啥in查詢比循環嵌套sql的查詢還要慢
- 使用git來創建屬于自己的composer包
- 翻頁獲取數據的時候又新增了數據
- 安全思路
- 月報
- PHP ?? 和 ?: 的區別
- PHP異步執行
- redis集群的目標是什么
- 大文件數據處理
- 性能瓶頸分析
- 命令行里輸出帶顏色的字體
- 面試問題合集
- 基礎
- 安全
- 算法
- 冒泡排序
- 快速排序
- 二分法查詢數組指定成員
- 字符查找匹配
- 令牌桶
- 漏桶
- 計數器
- 代理
- 協議
- http
- 狀態碼
- tcp
- udp
- Oauth2.0
- 設計模式
- 單例模式
- 適配器模式
- 工廠模式
- 觀察者模式
- 流程化
- 地址欄輸入網址到返回網頁的流程
- 題目收集
- 工具
- rabbitMq
- rabbitMQ用戶管理
- 生產者
- 消費者
- 支持TP5.*的think-queue
- 消息丟失
- 消費者報錯
- rabbitMQ配置優化
- 磁盤滿載導致服務掛掉
- PHP類庫
- rabbitMQ踩坑
- navicat
- vscode
- phpstorm
- 激活碼
- markdown
- PHP自定義類庫
- 工具類
- 領導力
- 任務分配
- 代碼組織
- 不要重復
- 避免污染
- 接口定義規范
- 小業務需求
- 獲取充值面額組成
- 監控服務器CPU和內存
- shell腳本版本