大约 5 天以来,似乎毫无征兆地,我的 Linux 服务器开始时不时地锁定。
据我从 top 和 iotop 命令中了解,当它开始发生时,模式总是一样的:
一个或多个 httpd 进程(通常是一个)挂起并开始消耗 100% 的 CPU 能力,%wa 接近 100%,在 iotop 中我看到几个 httpd 进程在 IO 列中占比为 99.99%。
我还通过 apache 在这台机器上运行 SVN 服务器,而我一直能够重现这种情况的一种方法是执行 SVN 提交新文件或从此服务器上的存储库执行 SVN 更新(我是唯一使用此 SVN 存储库的人)。这将始终成功重现这种情况,但直到最近,我在签入/退出 SVN 时都没有遇到任何问题。
但有时它的发生似乎根本就没有任何可察觉的原因。
因此,看起来我的 Apache 存在一些问题,导致其进程在某些触发因素下消耗大量的读/写。
我想知道是否有人可以帮助我发现这个问题。
编辑:好的,现在它又发生了:
这是顶部:
[root@server ~]# top
top - 10:56:54 up 2:59, 5 users, load average: 171.46, 70.35, 27.01
Tasks: 328 total, 2 running, 326 sleeping, 0 stopped, 0 zombie
Cpu(s): 1.9%us, 2.0%sy, 0.0%ni, 0.0%id, 96.1%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 2021144k total, 1968192k used, 52952k free, 2500k buffers
Swap: 4194288k total, 2938584k used, 1255704k free, 39008k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
10390 apache 20 0 2774m 936m 6200 D 2.0 47.4 1:52.27 httpd
2149 root 20 0 927m 13m 1040 S 0.7 0.7 1:50.46 namecoind
11 root 20 0 0 0 0 R 0.3 0.0 0:30.10 events/0
23 root 20 0 0 0 0 S 0.3 0.0 0:17.88 kblockd/1
2049 root 20 0 382m 4932 2880 D 0.3 0.2 0:03.67 httpd
2144 root 20 0 1702m 69m 1164 S 0.3 3.5 5:19.68 bitcoind
6325 root 20 0 15164 1100 656 R 0.3 0.1 0:11.09 top
10311 apache 20 0 387m 9496 7320 D 0.3 0.5 0:01.89 httpd
10313 apache 20 0 391m 10m 7364 D 0.3 0.5 0:02.40 httpd
10466 apache 20 0 399m 12m 7392 D 0.3 0.7 0:02.41 httpd
10599 apache 20 0 391m 9324 7340 D 0.3 0.5 0:00.15 httpd
10628 apache 20 0 384m 7620 4052 D 0.3 0.4 0:00.01 httpd
10633 apache 20 0 384m 7048 3504 D 0.3 0.3 0:00.01 httpd
10634 apache 20 0 384m 8012 4048 D 0.3 0.4 0:00.02 httpd
10638 apache 20 0 400m 22m 9.8m D 0.3 1.1 0:01.93 httpd
10640 apache 20 0 385m 8288 4028 D 0.3 0.4 0:00.03 httpd
10641 apache 20 0 401m 21m 6376 D 0.3 1.1 0:01.45 httpd
10759 apache 20 0 385m 8816 3480 D 0.3 0.4 0:01.45 httpd
10773 apache 20 0 384m 8044 3464 D 0.3 0.4 0:00.02 httpd
这是 iotop 快照:
Total DISK READ: 5.93 M/s | Total DISK WRITE: 0.00 B/s
TID PRIO USER DISK READ DISK WRITE SWAPIN IO> COMMAND
10732 be/4 apache 3.76 K/s 0.00 B/s 0.00 % 58.48 % httpd
876 be/3 root 0.00 B/s 52.68 K/s 0.00 % 52.98 % [jbd2/dm-1-8]
10906 be/4 root 124.17 K/s 0.00 B/s 0.00 % 23.03 % sh -c [ -x /usr/local/psa/admin/sbin/backupmng ] && /usr/local/psa/admin/sbin/backupmng >/dev/null 2>&1
2156 be/4 root 206.94 K/s 0.00 B/s 0.00 % 21.15 % bitcoind
10904 be/4 mysql 0.00 B/s 0.00 B/s 0.00 % 18.94 % mysqld --basedir=/usr --datadir=/var/lib/mysql --user=mysql --log-error=/var/log/mysqld.log --pid-file=/var/run/mysqld/mysqld.pid --socket=/var/lib/mysql/mysql.sock
10773 be/4 apache 7.53 K/s 0.00 B/s 0.00 % 14.77 % httpd
10641 be/4 apache 15.05 K/s 0.00 B/s 0.00 % 11.57 % httpd
10399 be/4 apache 1057.29 K/s 0.00 B/s 43.16 % 10.56 % httpd
10682 be/4 sw-cp-se 158.03 K/s 0.00 B/s 0.00 % 7.45 % sw-engine-cgi -c /usr/local/psa/admin/conf/php.ini -d auto_prepend_file=auth.php3 -u psaadm
10774 be/4 apache 3.76 K/s 0.00 B/s 0.00 % 6.53 % httpd
10624 be/4 apache 0.00 B/s 0.00 B/s 0.00 % 5.53 % httpd
10356 be/4 apache 899.26 K/s 0.00 B/s 35.52 % 4.01 % httpd
10795 be/4 apache 0.00 B/s 0.00 B/s 0.00 % 3.93 % httpd
10804 be/4 apache 7.53 K/s 0.00 B/s 0.00 % 3.08 % httpd
4379 be/4 root 2.89 M/s 0.00 B/s 99.99 % 0.00 % namecoind
10619 be/4 apache 462.80 K/s 0.00 B/s 7.80 % 0.00 % httpd
10636 be/4 apache 3.76 K/s 0.00 B/s 0.00 % 0.00 % httpd
10716 be/4 mysql 105.35 K/s 0.00 B/s 5.92 % 0.00 % mysqld --basedir=/usr --datadir=/var/lib/mysql --user=mysql --log-error=/var/log/mysqld.log --pid-file=/var/run/mysqld/mysqld.pid --socket=/var/lib/mysql/mysql.sock
1988 be/4 root 18.81 K/s 0.00 B/s 0.00 % 0.00 % spamd_full.sock
我还对 pid 10390 运行了 lsof -p,它位于 top 命令的顶部,这是底线,我可以从中看到这是什么请求,它显示 CLOSE_WAIT:
httpd 10390 apache 34u IPv6 315879 0t0 TCP default-domain.com:https->crawl-66-249-65-91.googlebot.com:42907 (CLOSE_WAIT)
但我还是不确定究竟是什么原因导致了这一切的发生?
我终止了该服务,但 %wa 和平均负载仍然很高,我还停止了 mysqld 和其他服务。它实际上只有在我完全停止 httpd 后才会停止,即使这样,我也无法启动它,除非通过“netstat -tulpn”找到剩余的挂起的 httpd 进程,然后终止它们或执行“killall -9 httpd”,等待一段时间让它循环遍历所有这些进程,然后执行 /etc/init.d/httpd start
答案1
首先,你的内存已经不足了。
您的 VPS 有 2GB 的 RAM 和 4GB 的交换空间。2GB 的 RAM 已全部用完,交换空间可能已用完 3/4。此时,在我管理的任何系统上,都会出现重复的警报每五分钟除非有人承认这个问题,否则它就是如此严重。
因此你需要弄清楚到底是什么占用了所有的内存。不幸的是这可能很难。
我可以看到一个 Apache 进程独自的使用了将近 1GB 的内存。这显然是一个异常值,因为其他大多数应用程序使用的内存都不足 22MB。
这很困难的原因是 Apache 允许您将诸如 Perl 或 PHP 之类的语言直接嵌入到进程中,并且几乎可以肯定这样的脚本已经失控并耗尽了您的所有 RAM。
此时,您的系统所能做的就是不断地进行交换(这正是它所iotop
显示的),直到有人用合适的位置对它仁慈一点kill -9
。
因此,您的下一步是尝试找出哪个脚本出了问题并消耗了所有 RAM。
答案2
10390 apache 20 0 2774m 936m 6200 D 2.0 47.4 1:52.27 httpd
2049 root 20 0 382m 4932 2880 D 0.3 0.2 0:03.67 httpd
10311 apache 20 0 387m 9496 7320 D 0.3 0.5 0:01.89 httpd
10313 apache 20 0 391m 10m 7364 D 0.3 0.5 0:02.40 httpd
10466 apache 20 0 399m 12m 7392 D 0.3 0.7 0:02.41 httpd
10599 apache 20 0 391m 9324 7340 D 0.3 0.5 0:00.15 httpd
10628 apache 20 0 384m 7620 4052 D 0.3 0.4 0:00.01 httpd
10633 apache 20 0 384m 7048 3504 D 0.3 0.3 0:00.01 httpd
10634 apache 20 0 384m 8012 4048 D 0.3 0.4 0:00.02 httpd
10638 apache 20 0 400m 22m 9.8m D 0.3 1.1 0:01.93 httpd
10640 apache 20 0 385m 8288 4028 D 0.3 0.4 0:00.03 httpd
10641 apache 20 0 401m 21m 6376 D 0.3 1.1 0:01.45 httpd
10759 apache 20 0 385m 8816 3480 D 0.3 0.4 0:01.45 httpd
10773 apache 20 0 384m 8044 3464 D 0.3 0.4 0:00.02 httpd
这表明很多 apache 进程处于 D 状态。Linux 计算平均负载的方式是将正在运行的进程 (R) + 处于不间断状态的进程 (D) 相加
您可以使用 top 命令轻松找出这些进程,或者您可以使用
ps auwx | awk '$8 ~ "D"'
因此,从输出来看,您的主要问题是 I/O。请在出现问题时运行以下命令,然后粘贴输出进行分析
sar -u 1 10 --> look for iowait
sar -q 1 10 --> look for load avg
iowait -x 1 10 --> to get a real picture of I/O
iotop --> to see what process causing I/O and its avilable >=5.8
echo t > /proc/sysrq-trigger
blktrace --> if you want to dig more about I/O and use to see per I/O basis,I created a video related to that,hope that is helpful
https://www.youtube.com/watch?v=s0XSWbIF84I&list=PLckUzKjgYDgajJVYOjNztS6Q4SOho0RKY&index=7
补充一下,您不能杀死 D 状态进程,在进程处于不间断睡眠状态的情况下,D'状态将不会响应信号,任务被阻止时发送的任何信号都会在进程返回到“R”或“S”状态后立即传递给进程(通常是在 IO 或其他内核活动完成之后)。
来自维基百科的专家
An uninterruptible sleep state is a sleep state that won't handle a signal right away. It
will wake only as a result of a waited-upon resource becoming available or after a time-
out occurs during that wait (if specified when put to sleep). It is mostly used by device
drivers waiting for disk or network IO (input/output). When the process is sleeping
uninterruptibly, signals accumulated during the sleep will be noticed when the process
returns from the system call or trap.