php-fpm 和 nginx 的奇怪性能波动

Cer*_*era 6 php performance nginx load-testing php-fpm

我正在针对 Web 服务运行负载测试。这是一个运行在 php-fpm 和 nginx 上的 php 应用程序,带有 fastcgi。有一个 MySQL 后端仅用于小型读取。

我总是看到一个奇怪的模式:性能稳定并随着流量的增加而可预见地增加,但在高峰期变得不稳定:CPU 使用率不断波动。

这是我看到的性能模式(用 可视化nmon):

在此处输入图片说明

下降总是与我的负载测试工具 - locust.io - 在它完成上升到我为测试设置的峰值水平时的短暂暂停同时发生。

我的假设:在这短暂的时刻,php-fpm主人认为负载已经消失并开始杀死工人;当流量在片刻之后全面恢复时,它无法足够快地响应。

我不太明白的是为什么它永远无法完全回到它的摆动中:我看到负载均衡器后面的所有 4 个应用程序服务器无限期地出现这种波动。

这是我的 php-fpm 池配置:

[www]
user = www-data
group = www-data
listen = /var/run/php5-fpm.sock
listen.group = www-data
listen.mode = 0660
pm = dynamic
pm.max_children = 100
pm.start_servers = 40
pm.min_spare_servers = 40
pm.max_spare_servers = 100
pm.max_requests = 10000
Run Code Online (Sandbox Code Playgroud)

我已经确认这不是数据库的问题 - 在将 MySQL 读取从站的数量增加一倍后,我看到了完全相同的行为。

这是什么原因造成的?我怎样才能阻止它?

编辑:

这是一个图表,展示了我所看到的。请注意,故障率通常会在 user_count 达到峰值时出现峰值,然后逐渐回落。

user_count vs fail_ratio

mc0*_*c0e 0

磁盘 IO 和锁定发生了什么?据推测,如果您的进程受 CPU 限制,达到了发生变化的程度,则说明其他东西正忙,而且很可能是您的磁盘。

您是否达到了内存限制而导致开始交换?您的 PHP 进程使用了​​多少 RAM (RSS)?您有多少可用内存?如果减少 PHP 进程的数量,性能是否会出现类似的波动?波动出现在什么水平?

请注意,这pm.max_children = 100可能太高了。除非您正在处理长时间运行的请求(例如大下载),否则您最好大幅减少它。在不知道系统正在做什么的情况下,我犹豫是否要指定一个数字,但 5-40 范围内的数字可能会效果更好。pm.max_requests 也可能太高。你可能会发现你没有得到什么好处,如果超过 100 左右,则更可能会显着降低,并且如果 php 运行的内容高度可变且消耗内存,或者你有内存泄漏,那么你会做得更好进一步减少它。如果您确实不知道什么有效,请从大约 30 个设置中的每一个开始进行试验。

PHP 是否生成会话?它们是如何存储的?如果它们位于文件系统上,那么它是什么类型的文件系统?在某些情况下,您会遇到锁定它们所在目录的瓶颈。为它们使用散列目录结构或使用例如 memcached 可以帮助解决这个问题。

strace 对 PHP 进程运行报告所花费的时间是什么?您可以使用以下复合命令来查看:

(ps wwaux | grep '^www-data.*php' |  awk '{print $2}' \
  | xargs -n 1 -P 32 strace -r -p ) 2>&1 
  | perl -ne '($n) = /^ *(\d*\.\d*)/; print "$n\t$_" if ((defined $n) and ($n > 0.01))'
Run Code Online (Sandbox Code Playgroud)