![诊断 Apache CPU/内存/进程峰值](https://linux22.com/image/754294/%E8%AF%8A%E6%96%AD%20Apache%20CPU%2F%E5%86%85%E5%AD%98%2F%E8%BF%9B%E7%A8%8B%E5%B3%B0%E5%80%BC.png)
我有一台运行 Ubuntu 18.04 的服务器,该服务器的 CPU 一直处于峰值状态,几乎每天会导致 Apache 停止运行一两次。该服务器运行几个网站 - 所有 php 和 mysql 驱动的应用程序。以下是我研究过的一些细节:
MySQL的:已启用慢查询日志,并设置为记录耗时超过 1 秒的查询。在峰值之后查看此日志没有发现任何特别之处。没有值得一提的长时间运行的查询。
计划任务:我检查了服务器上运行的所有用户 cron 作业,在这些峰值出现时没有发生任何事情。只有几个 CPU 密集型作业,它们在凌晨 3 点左右运行,大约需要 5 分钟才能完成。
PHP的:max_input_time
和都max_execution_time
设置为 60 秒,memory_limit
为 64M(这是一台 16GB 的服务器,通常不会接近最大内存使用量)。
阿帕奇:我们的主机 (Linode) 有一个名为 Longview 的工具,它可以显示与 Apache 相关的各种诊断信息。尽管资源消耗量激增,但请求似乎以正常速率发生。手动检查访问日志证实了这一点。以下是 Longview 中 Apache 选项卡的屏幕截图,显示了今天早上 Workers、CPU 和 RAM 的激增 - 以及相对正常的请求速率:
我还在 Apache 访问日志中添加了标志,以显示每个请求的时间和 I/O 数据。日志格式是time:%T input:%I output:%O
。所有请求或响应的大小都不是特别大(我见过的最大响应可能只有 1MB,而且是针对一张图片的)。唯一突出的是“处理请求所用的时间”,这是一个标志%T
。早上某个时候,许多看似正常的请求需要 5-10 分钟才能完成,原因不明。
我现在完全不知所措了。我该如何诊断引发此问题的事件?
答案1
有趣的是,9 点钟的时候,Apache 的负载非常大,不得不启动额外的工作线程来处理请求高峰。启动新线程需要时间。
如果您增加 apache 已准备好处理请求的待命工作线程的数量,您就可以吸收这种激增。
上午 9 点左右肯定有什么东西给服务器带来了负载。检查您的 Apache 日志,看看当时发出了哪些请求。这些请求看起来正常吗?您发现它与当天其他时间有什么不同?某个 PHP 脚本的访问量是否比平时更高?您的用户是否在一天中的不同时间执行了不同的事情?也许是生成报告,或者是特定时间的事情。
作为一个经验丰富的猜测,上午 9 点是工作日开始的时间,因此这可能是许多客户端同时启动和身份验证的结果。登录高峰。但是,我不知道您使用的是哪种应用程序,因此这可能不相关(如果站点是公开的且没有任何身份验证)。
这段时间内正在运行哪些 PHP 脚本?这段时间内有多少用户有会话?这是否不寻常?这段时间内正在运行哪些数据库查询?这是否与一天中的其他时间有很大不同?
它是否是某种网络机器人,例如谷歌爬虫在为您的页面编制索引时过于激进,如果是的话,请更新您的 robots.txt 或阻止/限制其速率。
当时的带宽使用情况如何?用户此时是否正在下载/上传大量数据?
考虑对资源和进程进行更多监控。只需查看 apache 即可,但如果 php/mysql 已重新登录,则可能也有线索。监控所有指标和进程将为您提供更多信息。
此时也请检查一下 /var/log 消息。您的内核可能也耗尽了资源。
最后要考虑的是,如果您的机器是虚拟机或容器,它可能会与该裸机服务器实例上的其他虚拟机竞争资源。因此,您的负载模式完全相同,但其他一些峰值虚拟机正在影响您的响应能力。您的服务提供商将能够为您提供此信息。
祝你好运。
答案2
我建议你加上%D
——”处理请求所需的时间(以微秒为单位)。“标记您的Apache 日志.
CPU 使用率过高主要源于数据库使用情况。
这可能不是来自单个 SQL 查询,而是来自数千个小型 SQL 查询在 PHPforeach(){}
循环中。
如果您在 Apache 日志中没有发现任何缓慢的请求,您可以启用完整的 SQL 查询日志在MySQL。这将向您显示用户的所有 SQL 查询。之后您可以对其进行静态分析。