0%

PHP-FPM如何合理设置max_chindren和pm模式,包括开启status监听

php-fpm如何合理设置max_chindren和pm模式,包括开启status监听

开启status获得执行状态

启用php-fpm状态功能

1
2
3
vi /etc/php-fpm.d/www.conf
修改:
pm.status_path = /status

nginx配置

1
2
3
4
5
6
7
8
9
10
11
server {
.
.
.
location ~ ^/status$
{
include fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $fastcgi_script_name;
}
}

重启nginx和php-fpm

打开status页面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@b04f945297ac ~]# curl http://visit.ma/status
pool: www
process manager: dynamic
start time: 23/Jul/2018:15:32:09 +0800
start since: 1055
accepted conn: 9
listen queue: 0
max listen queue: 0
listen queue len: 128
idle processes: 5
active processes: 1
total processes: 6
max active processes: 1
max children reached: 0
slow requests: 0

参数详解

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状态页比较个性化的一个地方是它可以带参数,可以带参数jsonxmlhtml并且前面三个参数可以分别和full做一个组合

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
curl http://visit.ma/status?json
curl http://visit.ma/status?xml
curl http://visit.ma/status?html
curl http://visit.ma/status?full

[root@b04f945297ac ~]# curl http://visit.ma/status?full
pool: www
process manager: dynamic
start time: 23/Jul/2018:15:32:09 +0800
start since: 1240
accepted conn: 10
listen queue: 0
max listen queue: 0
listen queue len: 128
idle processes: 5
active processes: 1
total processes: 6
max active processes: 1
max children reached: 0
slow requests: 0

************************
pid: 5466
state: Idle
start time: 23/Jul/2018:15:32:09 +0800
start since: 1240
requests: 2
request duration: 99
request method: GET
request URI: /status
content length: 0
user: -
script: -
last request cpu: 0.00
last request memory: 2097152
************************
pid: 5467
state: Idle
start time: 23/Jul/2018:15:32:09 +0800
start since: 1240
requests: 2
request duration: 184
request method: GET
request URI: /status?full
content length: 0
user: -
script: -
last request cpu: 0.00
last request memory: 2097152


这里重点说下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

使用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_serverspm.min_spare_serverspm.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
2
3
4
5
6
7
memory_limit = 256M
pm = dynamic
pm.max_children = 256
pm.start_servers = 32
pm.min_spare_servers = 16
pm.max_spare_servers = 32

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进程。

http://www.zhanghongliang.com/article/1300

http://www.ttlsa.com/php/use-php-fpm-status-page-detail/