服务器是centos,1核1G内存,上面挂了一个网站,最近发现时不时挂掉,进服务器重启一下服务又能用了,但是登录的时候看到这个提示:

1killed process 859(mysql) total-vm...

问题

上面一大列这样的提示,查找之后才知道这是linux一种内存控制机制:oom killer机制.

这种机制简单粗暴,就是在系统内存不够的时候,直接按照顺序杀掉内存占用最高的服务,结果就是PHP进程php-fpm一直被杀,网站直接打不开,打开服务器看了一下,确实是这样。

这是重启被关闭的MySQL服务后的情况:

killed-process-859mysql-total-vm…-1.png

还以为是内存不足,所以加了1G的swap虚拟内存,发现照样被塞满,所以问题肯定不是服务器配置不够的问题,而是网站的问题。

盯着看了一会,果然发现存在多个php-fpm进程,内存直接又爆了。一查才发现是php配置的问题,细想确实也是,这个服务器才放了一个网站,访问量也不高(伤心),内存怎么也不能撑爆才对。

解决办法

 1# 编辑php-fpm配置文件:
 2vim /etc/php-fpm.d/www.conf
 3
 4
 5# 将以下几行
 6pm = dynamic
 7pm.max_children = 75
 8pm.process_idle_timeout = 10s
 9
10# 改为
11pm = ondemand
12pm.max_children = 50
13pm.process_idle_timeout = 10s

pm = dynamic:#如何控制子进程,选项有static(静态)ondemand(经请求)dynamic(动态)static对于专用服务器,pm可以设置为static,如果选择static,则由pm.max_children指定固定的子进程数。 ondemand经过请求才会产生php-fpm子进程。 dynamic如果选择dynamic,则由以下参数决定:

  • pm.max_children   # 子进程最大数
  • pm.start_servers   # 启动时的进程数
  • pm.min_spare_servers # 保证空闲进程数最小值,如果空闲进程小于此值,则创建新的子进程
  • pm.max_spare_servers # 保证空闲进程数最大值,如果空闲进程大于此值,此进行清理

对于内存大的服务器(比如8G以上)来说,指定静态的max_children实际上更为妥当,因为这样不需要进行额外的进程数目控制,会提高效率。

对于内存小的服务器,使用动态方式,具体最大数量根据 内存/20M 得到。比如512M的VPS,建议pm.max_spare_servers设置为20。至于pm.min_spare_servers,则建议根据服务器的负载情况来设置,比较合适的值在5-10之间。 问题就解决了。

实际上,这只是对于小内存VPS的取巧方法,例如512M内存,可是1G内存以上都不建议这样设置,这样设置网页打开速度会变慢,所以,如果是想做好一个对外的网站,更实际的做法应该是加内存,起码加到1G,如果访问量低,甚至只是自己玩玩,就可以用这个方法。

一些可用的命令:

1# 查看php-fpm的进程个数
2ps -fe |grep "php-fpm"|grep "pool"|wc -l
3
4# 查看每个php-fpm占用的内存大小
5ps -ylC php-fpm --sort:rss