一、发现问题,内存不断增高,导致系统奔溃

二、观察进程内存占用,查看什么程序占用内存

使用命令:按内存排序查看

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配置参数:

  1. max_children: php-fpm最大可执行进程数
  2. 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.

四、问题解决后的情况