PHP内存泄漏,内存占用不断增大导致系统奔溃
一、发现问题,内存不断增高,导致系统奔溃
二、观察进程内存占用,查看什么程序占用内存
使用命令:按内存排序查看
ps -aux --sort -pmem | less
重启系统的时候占用内存情况
# free
total used free shared buff/cache available
Mem: 16268028 1160944 9936340 592 5170744 14717860
# ps -aux --sort -pmem | less
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
www 20450 0.1 0.1 47856 24216 ? S Jun21 2:39 nginx: worker process
www 20448 0.1 0.1 47932 24212 ? S Jun21 2:16 nginx: worker process
www 20452 0.1 0.1 47988 24052 ? S Jun21 3:28 nginx: worker process
www 20449 0.1 0.1 47864 23952 ? S Jun21 2:20 nginx: worker process
www 22041 0.8 0.1 388024 18680 ? S 14:04 0:00 php-fpm: pool www
www 22036 0.9 0.1 314596 18504 ? S 14:04 0:00 php-fpm: pool www
www 22030 0.8 0.1 314288 18444 ? S 14:04 0:00 php-fpm: pool www
www 22032 0.8 0.1 314308 18312 ? S 14:04 0:00 php-fpm: pool www
www 22037 0.9 0.1 314288 18284 ? S 14:04 0:00 php-fpm: pool www
www 22035 0.8 0.1 314300 18232 ? R 14:04 0:00 php-fpm: pool www
www 22052 0.8 0.1 314308 18220 ? S 14:04 0:00 php-fpm: pool www
www 22024 0.8 0.1 314340 18172 ? S 14:04 0:00 php-fpm: pool www
过一段时间在查看内存占用情况,发现 php-fpm 占用的内存在随时间不断变大
# free
total used free shared buff/cache available
Mem: 16268028 7726664 3071276 540 5470088 8150480
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
www 20458 0.6 1.1 563248 182668 ? S Jun21 12:59 php-fpm: pool www
www 20474 0.6 1.1 561788 182156 ? S Jun21 13:00 php-fpm: pool www
www 20461 0.6 1.1 562100 182152 ? S Jun21 12:59 php-fpm: pool www
www 20464 0.6 1.1 562216 182036 ? S Jun21 13:01 php-fpm: pool www
www 20462 0.6 1.1 562224 181984 ? S Jun21 12:59 php-fpm: pool www
www 20481 0.6 1.1 562184 181944 ? S Jun21 12:56 php-fpm: pool www
www 20472 0.6 1.1 561908 181936 ? S Jun21 12:59 php-fpm: pool www
www 20467 0.6 1.1 562132 181920 ? R Jun21 12:59 php-fpm: pool www
三、解决问题
从上面的数据分析,可以看出我们的php运行时间越长,占用的内存就会越高。而这种情况,很多时候是因为第三方库或者自己写的代码存在内存泄漏,如果不定期重启 PHP-CGI 进程,造成内存使用量不断增长,直接导致服务器奔溃。
PHP-FPM 为我们提供了这样一个功能,只要达到指定请求数量的PHP-CGI进程,就会直接kill,重新建立一个children
两个重要的php-fpm配置参数:
- max_children: php-fpm最大可执行进程数
- max_requests: 每个进程请求多少次后就自动结束,然后重新建立一个children
根据服务器配置这两个参数就可以避免内存泄漏导致服务器直接奔溃的问题了
这里贴上几个参数的配置说明
Choose how the process manager will control the number of child processes.
; Possible Values:
; static - a fixed number (pm.max_children) of child processes;
; dynamic - the number of child processes are set dynamically based on the
; following directives. With this process management, there will be
; always at least 1 children.
; pm.max_children - the maximum number of children that can
; be alive at the same time.
; pm.start_servers - the number of children created on startup.
; pm.min_spare_servers - the minimum number of children in 'idle'
; state (waiting to process). If the number
; of 'idle' processes is less than this
; number then some children will be created.
; pm.max_spare_servers - the maximum number of children in 'idle'
; state (waiting to process). If the number
; of 'idle' processes is greater than this
; number then some children will be killed.
; ondemand - no children are created at startup. Children will be forked when
; new requests will connect. The following parameter are used:
; pm.max_children - the maximum number of children that
; can be alive at the same time.
; pm.process_idle_timeout - The number of seconds after which
; an idle process will be killed.
; Note: This value is mandatory.
四、问题解决后的情况
每过一段时间进程池重启