我们有这个 apache 进程,它不时变成 io-bound。使用atop可以看出是写操作。
使用lsof -p <PID>
我们可以看到 httpd 进程打开的文件列表。首先我们认为“日志”文件一定是问题所在。所以我们将它们关闭只是为了测试。但是写入操作仍在继续。
我们将继续测试其他一些东西。例如,我们经常使用 php 会话变量。也许 php 会话文件得到了所有的写作。
但是有没有办法快速识别被 httpd 进程写入的文件?这样我们就可以集中精力处理这些文件。
更新:
我们按照建议使用了 strace 命令。这是输出中的两行。
write(23, "\27\0\0\0\3SET CHARACTER SET utf8", 27) = 27
write(23, "\17\0\0\0\3SET NAMES utf8", 19) = 19
我们在此服务器上没有 mysql 进程。那么 strace 是否也显示了正在写入以太网端口的内容?
UPDATE2:在高 io 负载期间,消耗大部分写入资源的进程将以下输出提供给strace -e trace=write -p <PID>
:
--- SIGCHLD (Child exited) @ 0 (0) ---
write(9, "!", 1) = 1
write(19, "OPTIONS * HTTP/1.0\r\nUser-Agent: Apache (internal dummy connection )\r\n\r\n", 70) = 70
但是我无法弄清楚这些被写入的位置。
UPDATE3:尝试了以下命令,它将向我显示所有打开以进行写入的文件:
lsof | grep -e "[[:digit:]]\+w"
以下是我无法检查的仅有的两行。其他文件没有显示任何重要的写入活动。是否可以将以下项目暂时写入硬盘?
httpd 14173 apache 9w FIFO 0,6 205676000 pipe
httpd 14173 apache 1w CHR 1,3 3346 /dev/null
找到的原因:
最后我们发现 io-boundness 的原因是 php 会话文件。将 php 会话文件移动到另一个硬盘驱动器也会立即将 io-boundness 移动到该硬盘驱动器。可能我们会将会话移动到 Redis 或其他基于内存的系统。有趣的是,尽管下面的答案在技术上是正确的,但它们并没有引导我们找到会话文件,而是让我们继续查看系统的不同点。
我认为 lsof 是查看当前已打开文件的最佳工具
您确定要查看正确的流程吗?每个 apache“服务器”都是一个单独的进程,因此您应该在每个孩子上循环控制(您从
StartServers
指令中定义的数字开始)。要查看连接: