我运行的服务器有 4 个 vCPU、14GB RAM 和 250GB 存储空间。一个工作日(7 小时)内,我每分钟平均收到 400-500 个请求。
我已将 php-fpm 设置增加到最大子服务器数 40、启动服务器数 10、最小备用服务器数 10 和最大备用服务器数 30。然后将其配置为按需配置。
使用时atop -C
我可以看到大多数php-fpm
进程消耗 1-2% 的 CPU。大多数时候 2/3 的进程开始消耗 66-89% 的 CPU(相当持续)。
当这个变成 4/5+ 个进程时,CPU 会达到 350%^,并且每分钟仅承受大约 400-500 个请求的压力。
有没有办法可以确定是什么原因导致 php-fpm 进程消耗如此高的 CPU?我正在使用它pgbouncer
来池化 SQL 连接。这是一个 Laravel 项目,由于它使用 Active Record 设计模式,因此 SQL 查询不是最好的,但在多个进程上使用超过 80% 的 CPU(非常频繁)告诉我有些东西严重未优化或错误,但从 nginx 访问日志中,我看不到在 CPU 峰值期间应该导致它的任何原因 - 看起来像是临时请求,没有导出等。
下面是我看到的一个例子,至少有 3 个进程通常一直占用超过 60% 的 CPU,捕获的这段时间内请求指标约为 200,因此低于平均水平!Nginx 访问日志没有显示任何异常。
任何帮助或关于如何进一步调试的想法都将不胜感激。我正在等待将 App Insights 功能投入生产,以尝试使用 Azure App Insights 隔离问题。
这些php
进程很可能是由supervisorctl
服务产生的,因为有 5 个线程为队列工作者运行。
我正在使用文件系统进行会话,经过更多研究后,我可以在 nginx 错误日志中看到与 SO 问题相同的内容:https://stackoverflow.com/questions/35891537/laravel-maximum-execution-time-of-30-seconds-exceeded-in-vendor-symfony-finder
vmstat -w 5
接近2分钟的输出:
--procs-- -----------------------memory---------------------- ---swap-- -----io---- -system-- --------cpu--------
r b swpd free buff cache si so bi bo in cs us sy id wa st
3 1 60868 302760 1291416 8474048 0 0 3 94 3 2 7 9 83 1 0
3 0 60868 305652 1291420 8474100 0 0 0 184 3032 11293 22 40 37 0 0
6 0 60868 307456 1291420 8474152 0 0 0 102 3043 12776 26 40 33 0 0
1 0 60868 309116 1291420 8474436 0 0 0 235 2904 13905 26 39 34 1 0
2 0 60868 301588 1291428 8476964 0 0 0 1245 2935 15069 30 40 29 1 0
3 1 60868 281128 1291432 8490560 0 0 0 196 2627 13892 31 40 29 1 0
2 0 60868 303012 1291432 8484872 0 0 0 159 3759 13004 21 37 40 2 0
9 0 60868 301080 1291436 8479384 0 0 0 151 3281 12728 24 41 35 0 0
5 0 60868 313884 1291436 8478624 0 0 0 94 2999 13096 27 39 33 0 0
2 0 60868 310636 1291444 8477260 0 0 0 70 3204 11980 24 36 40 0 0
2 0 60868 309108 1291448 8477488 0 0 0 1542 2982 11453 20 29 50 0 0
1 0 60868 305752 1291448 8477648 0 0 0 78 3036 9900 18 28 54 0 0
2 0 60868 303772 1291448 8477816 0 0 0 133 2408 8044 14 18 67 0 0
3 0 60868 295540 1291448 8477884 0 0 0 158 2482 8559 16 22 61 0 0
1 0 60868 295684 1291452 8477888 0 0 0 105 2985 10358 20 28 52 0 0
0 0 60868 295620 1291460 8477884 0 0 0 42 2352 7613 13 17 69 0 0
1 0 60868 296772 1291464 8478040 0 0 0 134 2751 10899 14 19 67 0 0
1 0 60868 279304 1291468 8495716 0 0 0 534 2801 9469 15 20 63 2 0
3 0 60868 304536 1291472 8485952 0 0 0 59 3420 11658 17 22 59 2 0
1 0 60868 297360 1291476 8480584 2 0 2 97 3079 11568 22 30 48 0 0
1 0 60868 327652 1291476 8479708 0 0 0 220 2777 8600 16 27 56 1 0
我不确定这些是否准确,因为 ASP 在 Azure 中使用“虚拟磁盘”(因为它是一个 docker 容器)。
答案1
编辑:看来您使用的是 postgres,上面建议的命令等效于这个:
postgres=# select * from pg_stat_activity;
如果您怀疑 SQL 过载且未优化的请求耗时过长,您可能能够以 root 身份在 myqsl 上使用此查询来查看它:
SHOW FULL PROCESSLIST;
通过查看时间列,您可以识别长请求甚至是挂起的请求。
答案2
如果“top”显示 php-fpm 使用了最多的 CPU,那么来自 DBMS 的负载可能很小(后续评论也证实了这是在其他地方)。
查看这里的统计数据(虽然我不熟悉你使用的 top 版本)似乎有非常尽管页面交换不多,但内存使用率很高。您确实需要减少内存使用率。“每分钟大约 400-500 个请求”并不是一个很大的数量 - 特别是考虑到此服务器的大小,但容量问题(这会导致性能问题,然后进入反馈循环)与一次处理的请求数有关(到达率 x 响应时间)。
接下来要检查的是 opcache 的配置和大小是否正确。
如果这些方法不能解决您的问题,那么您将需要开始分析代码。运行分析器的数据捕获需要付出代价。建议您将一小部分流量分离到第二台主机,然后只在那里运行分析器。