NGINX/PHP-FPM CPU 峰值和失控进程

NGINX/PHP-FPM CPU 峰值和失控进程

最近我切换到 NGINX/PHP-FPM 来运行我的论坛。

大多数时候,网站运行良好,速度非常快,我对此非常满意。它运行在 AWS 的 13 核/30+GB 内存实例上,因此资源充足(之前使用 Apache 时是 8 核、16GB)。

所以,大多数时候我们有 6 或 7 个 PHP-FPM 进程,一切正常;

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
27676 apache    20   0  499m  34m  19m R 49.2  0.1   0:06.33 php-fpm
27669 apache    20   0  508m  48m  24m R 48.2  0.1   0:10.84 php-fpm
27661 apache    20   0  534m  75m  26m R 45.9  0.2   0:16.18 php-fpm
27671 apache    20   0  531m  69m  21m R 43.9  0.2   0:09.85 php-fpm
27672 apache    20   0  501m  41m  23m R 32.9  0.1   0:09.18 php-fpm
27702 apache    20   0  508m  40m  16m R 23.6  0.1   0:00.94 php-fpm

嗯,还算不错。占用了大量 CPU,但只有少数几个,所以还算可以。

然后,不知从何而来,我生成了一堆进程(上次有 52 个),并且每个其中一个占用了 8% 的 CPU。你不需要很了解这个就知道 52 * 8 是很多了。

现在,我已将 max_children 设置为 40(之前是 50)。

pm.max_children = 40
pm.start_servers = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 6
pm.max_requests = 100

php.ini 中的内存限制为 128mb。

所以,我明白了为什么会有这么多进程 - 没关系,我已经配置好了它们。我好奇的是,如果每个进程有 8% 的 CPU - 这是否太多了?也许我的进程存活的时间太长了?

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root     26575  0.0  0.0 499572  4944 ?        Ss   18:23   0:01 php-fpm: master process (/etc/php-fpm.conf)
apache   28161 16.1  0.1 516644 47588 ?        S    19:06   0:08 php-fpm: pool www
apache   28164 18.0  0.1 525044 59644 ?        S    19:06   0:07 php-fpm: pool www
apache   28166 18.6  0.1 513152 41388 ?        R    19:06   0:06 php-fpm: pool www
apache   28167 23.2  0.1 515520 47092 ?        S    19:06   0:07 php-fpm: pool www
apache   28168 15.2  0.1 515804 49320 ?        S    19:06   0:04 php-fpm: pool www
apache   28171 17.3  0.1 514484 43752 ?        S    19:06   0:04 php-fpm: pool www

当我写这篇文章时,是晚上 7:08 - 因此子进程已经运行了 2 分钟,并且可能在这段时间内提供了很多服务(目前论坛上有 700 人。)

所以 - 非常渴望听到建议/批评/意见。我最近有很多停机时间,我正准备再次设置 Apache,我很乐意坚持下去。

提前致谢。

编辑
这是 Bitnami 图表,显示了峰值及其发生的速度(这是 24 小时) CPU 使用率图表

编辑#2
nginx.conf 可以在这里找到。

编辑#3
我提高了我的数字。看起来不错,但还是让我有点紧张。

pm.max_children = 100
pm.start_servers = 25
pm.min_spare_servers = 25
pm.max_spare_servers = 50
pm.max_requests = 500

编辑#4
因此,我又遇到了几次停机,并设置了 Splunk 和 New Relic 来帮助我监控正在发生的事情。似乎没有 CPU 等待时间,而且我还有可用内存。

top - 17:30:37 up 10 days, 19:20,  2 users,  load average: 24.61, 37.34, 25.68
Tasks: 151 total,  20 running, 131 sleeping,   0 stopped,   0 zombie
Cpu0  : 71.8%us, 27.9%sy,  0.0%ni,  0.0%id,  0.0%wa,  0.0%hi,  0.3%si,  0.0%st
Cpu1  : 73.7%us, 26.3%sy,  0.0%ni,  0.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu2  : 70.8%us, 29.2%sy,  0.0%ni,  0.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Cpu3  : 69.3%us, 30.7%sy,  0.0%ni,  0.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:  35062648k total, 28747980k used,  6314668k free,   438032k buffers
Swap:        0k total,        0k used,        0k free, 16527768k cached

观察 Splunk 似乎不像是它的流量 - 我确实受到 Googlebot 的大量攻击,我对此感到怀疑,但没有什么具体的东西。

答案1

嗯,还算不错。占用了大量 CPU,但只有少数几个,所以还算可以

进程的工作量由其使用的 CPU 数量决定 - 因此,它是使用率百分比 x 使用时间。因此,如果您的 PHP 进程占用了大量 CPU,那么这通常是一件好事 - 这意味着它不会等待其他事情发生。从系统管理员的角度来看,您可以为其他任务提供更多 CPU - 但这将增加 PHP 进程处理请求所需的时间。

当然,如果请求以稳定的速率进入,则处理这些请求需要更长的时间,这意味着任何时候都会有更多的进程在工作(或等待调度),而更大的内存占用意味着可用于 VFS 缓存的内存更少。还存在调度程序将开始抢占任务而不是让它们让步的风险,这会降低整体吞吐量。

因此你应该目标是实现高 CPU 使用率!(但负载低)。

php.ini 中的内存限制为 128mb

这个值相当高,但是由于 CPU 使用率很高,这表明这不是什么大问题,除非每个请求都需要很长时间才能完成,并且进行大量的垃圾收集 - 在这种情况下,通过减少内存限制来强制更频繁地进行垃圾收集实际上可以提高性能。

我最近很空闲

不管怎样,我发现 APC 比 Xcache 可靠得多 - 从我在其他地方读到的内容来看,这似乎是趋势。我没有关于 Zend Optimizer+ 的任何经验/数据,它将与未来版本的 PHP 捆绑在一起。

我即将再次设置 Apache,并且我愿意继续这样做

在较低的流量下,Pre-fork apache + mod_php 明显比 nginx + php-fpm 快 - 但当负载/请求率相对于硬件容量而言为中高时(您似乎处于这种情况),nginx 似乎具有巨大的优势。

如果是我,我会仔细查看日志,看看峰值是否是由于流量增加/流量配置文件发生变化/响应时间发生变化造成的。同时仔细查看缓存和代码。您可以考虑临时针对实时站点运行分析器(使用 xhprof - 而不是生产系统的 xdebug)。

相关内容