php-fpm如何合理设置max_chindren和pm模式,包括开启status监听
开启status获得执行状态
启用php-fpm状态功能
1 | vi /etc/php-fpm.d/www.conf |
nginx配置
1 | server { |
重启nginx和php-fpm
打开status页面
1 | [root@b04f945297ac ~]# curl http://visit.ma/status |
参数详解
pool – fpm池子名称,大多数为www
process manager – 进程管理方式,值:static, dynamic or ondemand. dynamic
start time – 启动日期,如果reload了php-fpm,时间会更新
start since – 运行时长
accepted conn – 当前池子接受的请求数
listen queue – 请求等待队列,如果这个值不为0,那么要增加FPM的进程数量
max listen queue – 请求等待队列最高的数量
listen queue len – socket等待队列长度
idle processes – 空闲进程数量
active processes – 活跃进程数量
total processes – 总进程数量
max active processes – 最大的活跃进程数量(FPM启动开始算)
max children reached - 大道进程最大数量限制的次数,如果这个数量不为0,那说明你的最大进程数量太小了,请改大一点。
slow requests – 启用了php-fpm slow-log,缓慢请求的数量
php-fpm其他参数
php-fpm状态页比较个性化的一个地方是它可以带参数,可以带参数json、xml、html并且前面三个参数可以分别和full做一个组合
1 | curl http://visit.ma/status?json |
这里重点说下full参数详解
pid – 进程PID,可以单独kill这个进程. You can use this PID to kill a long running process.
state – 当前进程的状态 (Idle, Running, …)
start time – 进程启动的日期
start since – 当前进程运行时长
requests – 当前进程处理了多少个请求
request duration – 请求时长(微妙)
request method – 请求方法 (GET, POST, …)
request URI – 请求URI
content length – 请求内容长度 (仅用于 POST)
user – 用户 (PHP_AUTH_USER) (or ‘-’ 如果没设置)
script – PHP脚本 (or ‘-’ if not set)
last request cpu – 最后一个请求CPU使用率
last request memorythe - 上一个请求使用的内存
合理设置max_chindren和pm模式
使用htop命令查看单个php-fpm所申请的VIRT大小,我32G服务器是400左右(实际要除以8=M,就是:50M左右),如果按照每个进程消耗50M*1.5倍=75M左右,如果你的服务器内存是32G,我们假设可用于php-fpm的内存为60%=20G,则:20*1024/75=273,所以,一般我们建议max_chindren最大为273,最好还是设置为:8的倍数,所以我设置为256.
然后我们可以根据域名/status的结果来合理设置其他参数(pm.start_servers和pm.min_spare_servers和pm.max_spare_servers)
在php.ini中,我们可以看到memory_limit有一句这样的原文,Maximum amount of memory a script may consume (128MB)
,就是说单个进程使用的最大内存大小,这个参数吧,当然不能低于刚刚计算的75M了,一般我们可以设置为3倍,则75*3=225M左右(建议:128,256,512,1024…)
这里假如有攻击的话,max_chindren=256,memory_limit=256,256*256=64G,很明显会导致内存爆满,所以如果想又保持性能,又能一定程度上防止内存爆满,可以将max_chindren设置的低一点,memory_limit可以设置为每个进程消耗的值(一般不建议低于128M吧,如果是独立服务器的话)。
PHP-FPM 子进程数量,是不是越多越好?
当然不是,pm.max_chindren,进程多了,增加进程管理的开销以及上下文切换的开销。
更核心的是,能并发执行的 php-fpm 进程不会超过 cpu 个数。
如何设置,取决于你的代码
如果代码是 CPU 计算密集型的,pm.max_chindren 不能超过 CPU 的内核数。
如果不是,那么将 pm.max_chindren 的值大于 CPU 的内核数,是非常明智的。
国外技术大拿给出这么个公式:
在 N + 20% 和 M/m 之间。
N 是 CPU 内核数量。
M 是 PHP 能利用的内存数量。
m 是每个 PHP 进程平均使用的内存数量。
适用于 dynamic 方式。
static方式:M/(m * 1.2)
当然,还有一种保险的方式,来配置 max_children。适用于 static 方式。
先把 max_childnren 设置成一个比较大的值。
稳定运行一段时间后,观察 php-fpm 的 status 里的 max
active processes 是多少
然后把 max_children 配置比它大一些就可以了。
pm.max_requests:指的是每个子进程在处理了多少个请求数量之后就重启。
这个参数,理论上可以随便设置,但是为了预防内存泄漏的风险,还是设置一个合理的数比较好
所以,我的服务器32G内存设置为:
1 | memory_limit = 256M |
pm.max_children:静态方式下开启的php-fpm进程数量。
pm.start_servers:动态方式下的起始php-fpm进程数量。
pm.min_spare_servers:动态方式下的最小php-fpm进程数量。
pm.max_spare_servers:动态方式下的最大php-fpm进程数量。
如果dm设置为static,那么其实只有pm.max_children这个参数生效。系统会开启设置数量的php-fpm进程。
如果dm设置为static,那么其实只有pm.max_children这个参数生效。系统会开启设置数量的php-fpm进程。