php-fpm占用系统资源分析

2017-04-02 00:56:36

故障检测

1.别的先不管,先top看一下cpu、ram、swap哪个比较紧张。

 

 

由上图分析,可以看出共有602个进程,其中有601个进程休眠了。这好像有点不对劲,内核进程也就80个左右,加上memcached, nginx, mysqld,也不会超出90个。除了这些,剩下的只有php-fpm管理的php-cgi,难道是…?
CPU显示,CPU压力并不大,可以说没有压力。我们再看内存使用概要,发现4G的内存,消耗得所剩余无几(free+buffers), 95%以上的内存都已分配。交互空间使用情况,我们暂时不去关心。指令top还列出了占用资源最多的进程,运行时间最久(Time+)的mysqld(约 2小时)占用资源并不是最多。另外,再看php-cgi,单个php-cgi占用的内存也不算多。所以,可以大胆地猜想:服务器内存资源比较紧张,并没有被某个进程占用大量内存,有可能被某些挂起的进程占着内存没有释放。通过free进一步监控内存使用情况,验证我们的想法。
2.指令free,了解RAM资源使用情况。当然,你也可以查看文件/proc/meminfo

我们先来看Mem统计信息,total表示物理内存总量,约4G。used,表示已分配内存,分配了并不表示使用了,包括 (buffer&cached)。free指未分配的内存,buffers与cached表示分配了但还没有被使用的内存。第二行 (buffers/cache)的,used表示真正被使用了内存,由第一行的(used-buffer-cached)得到,free则表示还没有被使用的内存,由第一行的(free+buffer+cached)得到。Swap行则表示内存交换使用情况,少量的(不频繁地)swpd,是不会影响服务器性能的,因为系统需要将V类型的内存页面交换出去或者调整了buffer与cached的大小。但是频繁地swpd,则有可能意味着服务器物理内存不足,小于指定的swap额定值,需要换出内存页。

查看free结果的时候,我们主要查看第二行。一眼就能看出4G的内存,其中有3898M内存被用了,还有49M内存没有,都快用完了。这也证实了我们第一步的猜想,内存被用完。这里,我们进一步猜想,内存空间严重不足的情况下,进程会被blocked,系统会不断地将不用的数据换出so,将要用的数据读入si。我们能通过vmstat进一步验证,我们的这个猜想。

3.指令vmstat监控内存使用情况

作为对内存监控,我们比较关心swpd、free、si、so。一般系统不繁忙的状态下,我们看到swpd,so的值不会持续很高,经常为0。这里,我们看到swpd值为1.5G,以及free值很小,再一次表明物理内存不足。其中si报告了每秒从swap区移入到物理内存的内存总量,so报告了每秒从物理内存移出到swap区的内存总量。当然,si有时较大,并不要过份的焦虑,经常碰到一个程序需要较大内存来读写媒体文件时,si值就会变大。反倒是 so,它通常是一个内存紧缺的一个信号,如果长时间这个值一直保持较大的话,则很有可能内存不够,小额波动,可以不用理会。接下来,可以通过ps找出消耗内存的元凶。
4.指令ps找出消耗内存的元凶

[root@localhost ~]# ps -A --sort -rss -o comm,pmem,pcpu |uniq -c |head -15
1 COMMAND %MEM %CPU
1 mysqld 0.6 0.0
503 php-cgi 0.3 0.0
5 php-cgi 0.2 0.0
1 php-cgi 0.1 0.0
1 php-cgi 0.0 0.0
1 memcached 0.0 0.0
1 sshd 0.0 0.0
1 nginx 0.0 0.0
1 sshd 0.0 0.0
1 nginx 0.0 0.0
2 bash 0.0 0.0
3 nginx 0.0 0.0
1 sshd 0.0 0.0
1 nginx 0.0 0.0

指令ps比较常用,也比较简单。上面报告结果,我们一眼就可以命中php-cgi这个进程。虽然单个php-cgi占用内存并不算太大,但是503 个php-cgi进程,就有点恐怖了。几乎占尽了全部内存(503*0.3%)。我们可以猜想,php-cgi由php-fpm管理,是不是可以php- fpm的某个参数配置不当,导致打开过多的php-cgi进程。
5. 设置php-fpm进程数量管理
通过重新将php-conf.conf的max_children值设置为150,系统内存又恢复到正常使用情况。free、si、so、b均表示内存系统资源正常,没有压力。

php-cgi进程释放的内存并不会被系统立即回收,一个php-cgi大概占用20kb内存(取决于你加载的php extensions)。所以,有必要限制你启动的php-cgi进程数量。那么,这个数量多少合适呢,你可以在服务器高峰期通过top统计出php- cgi数量。也可以像php-fpm建议的那样,通过netstat -np | grep 127.0.0.1:9000来收集数据,通过设置max_children使等待的数量尽量小

6.一个php-cgi占用多少内存
一个php-cgi进程,大概占用多少内存呢,大概是20MB。可以通过pmap指令查看哪些地方占用了内存。所以,尽量不要加载不必要的php扩展模块,可以减少不必要的内存浪费。

[root@localhost etc]# pmap $(pgrep php-cgi |head -1)
6746: /usr/local/php/bin/php-cgi –fpm –fpm-config /usr/local/php/etc/php-fpm.conf
0000000000400000 6680K r-x– /usr/local/php/bin/php-cgi
0000000000c86000 268K rw— /usr/local/php/bin/php-cgi
0000000000cc9000 56K rw— [ anon ]
0000000005012000 2240K rw— [ anon ]
0000003efd200000 112K r-x– /lib64/ld-2.5.so
…….
00002ac28a7a5000 2048K —– /usr/local/php/lib/php/extensions/no-debug-non-zts-20060613/xhprof.so
00002ac28a9a5000 4K rw— /usr/local/php/lib/php/extensions/no-debug-non-zts-20060613/xhprof.so
00002ac28a9a6000 84K r-x– /usr/local/php/lib/php/extensions/no-debug-non-zts-20060613/apc.so
00002ac28a9bb000 2048K —– /usr/local/php/lib/php/extensions/no-debug-non-zts-20060613/apc.so
00002ac28abbb000 8K rw— /usr/local/php/lib/php/extensions/no-debug-non-zts-20060613/apc.so
00002ac28abbd000 32K rw— [ anon ]
00002ac28abd4000 40K r-x– /lib64/libnss_files-2.5.so
00002ac28abde000 2044K —– /lib64/libnss_files-2.5.so
00002ac28addd000 4K r—- /lib64/libnss_files-2.5.so
00002ac28adde000 4K rw— /lib64/libnss_files-2.5.so
00007fffa717e000 84K rw— [ stack ]
ffffffffff600000 8192K —– [ anon ]
total 154172K

 

 

 

约定几个目录

  • /usr/local/php/sbin/php-fpm

  • /usr/local/php/etc/php-fpm.conf

  • /usr/local/php/etc/php.ini

一,php-fpm的启动参数

1
2
3
4
5
6
7
8
9
10
11
12
13
#测试php-fpm配置
/usr/local/php/sbin/php-fpm -t
/usr/local/php/sbin/php-fpm -c /usr/local/php/etc/php.ini -y /usr/local/php/etc/php-fpm.conf -t
 
#启动php-fpm
/usr/local/php/sbin/php-fpm
/usr/local/php/sbin/php-fpm -c /usr/local/php/etc/php
  • 2021-02-03 16:52:27

    ios静态库和动态库区别

    Framework 是 Cocoa/Cocoa Touch 程序中使用的一种资源打包方式,可以将代码文件、头文件、资源文件(nib/xib、图片、国际化文本)、说明文档等集中在一起,方便开发者使用。Framework 其实是资源打包的方式,和静态库动态库的本质是没有什么关系。

  • 2021-02-03 16:57:34

    iOS中的动态库和静态库分析

    由于最近研究组件化后调试时二进制映射源码的功能,发现需要对开发中的动态库和静态库需要有一些了解。所以就有了这篇文章,由于只是了解,并没有深入到编译层面,所以本篇文章只是简单了解一些库的知识,并不深入。

  • 2021-02-03 16:58:39

    iOS静态库与动态库的区别与打包

    这篇主要是记录一下 iOS 下静态库与动态库的打包流程,以便以后用到时快速查阅,供自己也供大家学习记录。同时也简述了一下 动态库 与 静态库 的区别。

  • 2021-02-03 16:59:59

    iOS 静态库和动态库全分析

    库就是程序代码的集合,将 N 个文件组织起来,是共享程序代码的一种方式。从本质上来说是一种可执行代码的二进制格式,可以被载入内存中执行。

  • 2021-02-03 17:01:30

    iOS库 .a与.framework区别

    静态库:连接时完整地拷贝至可执行文件中,被屡次使用就有多份冗余拷贝。 动态库:连接时不复制,程序运行时由系统动态加载到内存,供程序调用,系统只加载一次,多个程序共用,节省内存。

  • 2021-02-03 17:13:58

    iOS - 封装静态库

    静态库:链接时完整的拷贝至可执行文件中,被多次使用就有多份冗余拷贝,.a的静态库 .framework的静态库

  • 2021-02-03 17:16:07

    iOS 中的动态库、静态库和 framework

    首先来看什么是库,库(Library)说白了就是一段编译好的二进制代码,加上头文件就可以供别人使用。 什么时候我们会用到库呢?一种情况是某些代码需要给别人使用,但是我们不希望别人看到源码,就需要以库的形式进行封装,只暴露出头文件。另外一种情况是,对于某些不会进行大的改动的代码,我们想减少编译的时间,就可以把它打包成库,因为库是已经编译好的二进制了,编译的时候只需要 Link 一下,不会浪费编译时间。

  • 2021-02-03 17:17:53

    iOS 同一个工程下打包不同的app

    应用图标,启动画面,应用启动后的首页都不一样。 有些课程(例如公务员考试和高考)是有目标考试的概念,不同的目标考试大纲是不一样的。拿高考来举例,北京的高考和上海的高考,就有着完全不一样的考试大纲。高考的文科和理科,又有着完全不同的考试科目。 有些课程会有一些自定义的界面,例如高考的应用可以设置昵称,有些课程的真题练习中是有推荐真题模块的,而有些课程又没有。 有些课程有扫描答题卡功能,有些课程有考前冲刺功能,有些课程有大题专项查看功能,而有些课程又没有上述功能。另外还有一些微小细节,但是解决方法和类似,所以就不一一展开说明。