我正在运行一个Web服务的负载testing。 这是一个运行在php-fpm和nginx上的使用fastcgi的php应用程序。 MySQL后端仅用于小型读取。
我总是看到一种奇特的模式:性能稳定,随着stream量的增加,性能会有所增加,但在高峰时刻性能会变得不稳定:CPU使用率不断波动。
这里是我看到的performance模式(用nmon可视化):

这个下降总是与我的负载testing工具locust.io在完成升级到我为testing设置的最高级别时的短暂停顿相符。
我的假设 :在这短暂的时刻, php-fpm主人认为负载已经消失,开始杀死工人; 在一会儿的交通恢复之后,它的响应速度不够快。
我不太明白的是,为什么它永远无法摆脱它:我看到负载均衡器背后的所有4个应用程序服务器无限期的波动。
这是我的php-fpm池configuration:
[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
我已经证实,这不是数据库的问题 – 我看到MySQL读取从站的数量翻倍后,完全相同的行为。
这是什么原因造成的? 我怎么能阻止它?
编辑:
这是一个图表,展示了我所看到的。 请注意,失败率通常会在user_count达到峰值时出现峰值,然后逐渐下降。

你的memory management呢? 最后几周我做了一些模拟testing,并把一台服务器带到了极限。 我看到很多内存的变化。 在我的情况下,大量的数据被带入交换而不是RAM来处理负载。 经过一次testing,我得到了一个奇怪的结果,没有使用内存,完成所有的交换。 也许这是下面的请求正在放缓。
这是一个示例图像,我的交换看起来像负载testing之后
磁盘IO和locking发生了什么? 想必如果你的进程是CPU绑定到一个点,那么其他事情是忙碌的,这很可能是你的磁盘。
你是否遇到会导致你开始交换的内存限制? 你的PHP进程使用多less内存(RSS)? 你有多less内存? 如果你敲回来的PHP进程的数量,你会得到类似波动的performance吗? 波动出现在什么水平?
请注意, pm.max_children = 100可能太高了。 除非你正在处理像下载量大的长时间运行的请求,否则你最好减less很多。 我毫不犹豫地指定一个数字而不知道系统在做什么,但可能在5-40范围内的东西会更好。 pm.max_requests也可能太高了。 你可能会发现,如果超过100个左右,你会得到很less的好处,而且更有可能出现严重的下降,如果php运行的是高度可变的内存消耗,或者你有内存泄漏,那么你会做的更好进一步减less它。 如果你真的不知道什么是有效的,那么从30个这些设置开始,然后进行实验。
PHP生成会话? 他们如何存储? 如果他们在一个文件系统上,它是什么types的文件系统? 在某些情况下,你可能会遇到一个locking目录的瓶颈。使用散列化的目录结构或者使用memcached可以帮助解决这个问题。
对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))'