httpd 进程 CPU 每隔 xx 秒就会激增至 100%+

httpd 进程 CPU 每隔 xx 秒就会激增至 100%+

这是我的第一篇帖子,不幸的是,由于运行一些个人网站和一个商业网站的专用服务器(Linux Centos 6)出现问题。

Server version: Apache/2.4.18 (Unix)
Server built:   Mar  7 2016 20:22:35
Cpanel::Easy::Apache v3.32.10 rev9999

root@server213-171-196-40 [~]# free
             total       used       free     shared    buffers     cached
Mem:      16212880   15939912     272968    1939060      65928   13730952
-/+ buffers/cache:    2143032   14069848
Swap:      4194296    1477616    2716680

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
[b] 2900 nobody    20   0 90636  14m 2408 R 99.1  0.1   0:07.42 httpd[/b]
   72 root      20   0     0    0    0 R 17.3  0.0   8:08.35 kswapd0
  436 root      20   0     0    0    0 S  2.3  0.0   1:54.42 md1_raid1
    1 root      20   0 19356  668  452 S  0.0  0.0   0:00.72 init
    2 root      20   0     0    0    0 S  0.0  0.0   0:00.00 kthreadd
    3 root      RT   0     0    0    0 S  0.0  0.0   0:00.03 migration/0
    4 root      20   0     0    0    0 S  0.0  0.0   0:00.37 ksoftirqd/0
    5 root      RT   0     0    0    0 S  0.0  0.0   0:00.00 stopper/0
    6 root      RT   0     0    0    0 S  0.0  0.0   0:00.05 watchdog/0
    7 root      RT   0     0    0    0 S  0.0  0.0   0:00.04 migration/1

上面是 httpd 进程“颠簸”时的一个例子。它显然会立即增加服务器的负载,当有 4 个 httpd 进程做同样的事情时,您可以想象网站会变得非常迟钝。通常,httpd 进程的运行速度在 0.1% 到 0.5% 之间,运行良好。

CPU 负载的峰值只是在周一凌晨才开始的,而我周日还没有重建 apache 或更改任何配置。

我运行了不少 wordpress 网站 - 我仔细检查了一下,发现当时插件有任何更新。

我的 Linux 技能有点有限,我为其中一个最大 httpd 进程选择了一个 PID,并尝试使用 strace -p 命令跟踪它在做什么

显示此内容以快速滚动过去。在我外行人看来,这像是 DOS 攻击?淹没了服务器?

1457649966.654499 read(114, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 1024) = 1024 <0.000005>
1457649966.654515 read(114, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 1024) = 1024 <0.000005>
1457649966.654531 read(114, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 1024) = 1024 <0.000005>
1457649966.654545 read(114, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 1024) = 1024 <0.000006>
1457649966.654559 read(114, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 1024) = 1024 <0.000005>
1457649966.654573 read(114, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 1024) = 1024 <0.000005>
1457649966.654587 read(114, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 1024) = 1024 <0.000005>

我显然是错的——在大约 10 秒的峰值内,我的日志文件输出超过 200 万行!因此,短时间运行的“读取”数量惊人。

失控进程的另一个踪迹:

root@server213-171-196-40 [/usr/local/iftop-0.17]# strace -c -p 23369
Process 23369 attached
^CProcess 23369 detached
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
100.00    0.044961           0   2367035           read
------ ----------- ----------- --------- --------- ----------------
100.00    0.044961               2367035           total

我实际上不明白那里发生了什么 - 我的猜测是某种东西以某种方式向我的 httpd 进程推送了大量噪音/空数据,并且每 20 秒/每隔几分钟这样做一次。

或者这完全是别的什么事情,而我已经完全偏离目标了。

我正在尝试将我的一些网站置于 cloudflare 之下,以便 a) 使用其 CDN 加速图形密集型网站,同时也尝试添加额外的防御层。目前还看不到任何效果。我甚至无法确定哪个 url/网站是原因,如果有的话。

服务器确实有 mod_security,带有标准规则集 - 我确实关闭了 ip 检查,因为在某处读到过它可能会减慢服务速度(虽然没有效果)。服务器有足够的内存(16 GB),4 个 CPU(8 核英特尔机器),并且峰值的 apache 进程显示内存使用量很小,都是 CPU。

PHP 版本 5.6.18(或 .19,需要仔细检查)。

Netstat 在“峰值”时不会显示任何单个 IP 有超过 20 个连接 - 并且服务器没有超载(我已经关闭了每天有超过 15,000 名访问者的繁忙网站,以消除流量问题)。

root@server213-171-196-40 [~]# netstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -n

      1 108.162.221.138
      1 108.162.246.252
      1 141.101.98.176
      1 173.245.50.109
      1 199.16.156.125
      1 213.128.67.90
      1 213.205.194.66
      1 222.186.34.163
      1 79.70.61.9
      1 86.128.207.3
      1 94.14.114.56
      1 95.151.139.42
      1 Address
      1 servers)
      2 108.162.222.88
      2 173.245.56.127
      4 86.4.247.37
      5 136.243.48.85
      6 78.147.41.131
      7 90.220.251.88

截至周一早上,服务器运行正常 - 但负载比现在更重。

来自httpd.conf:

Timeout 300
TraceEnable Off
ServerSignature Off
ServerTokens ProductOnly
FileETag All
StartServers 5
<IfModule prefork.c>
MinSpareServers 5
MaxSpareServers 10
</IfModule>
ServerLimit 256
MaxRequestWorkers 150
MaxConnectionsPerChild 15000
KeepAlive On
KeepAliveTimeout 5
MaxKeepAliveRequests 100

当前使用 prefork mpm,但我很高兴使用 event mpm 运行,我根据 WHM/CPANAL easyapache3 在“标准”pre-fork 设置下重建了 apache,看看重建和更改 apache 的配置是否可行,但是没有用。

如果你们当中有谁见过类似的跟踪输出,或者相同类型的 http 抖动,我很乐意听取您的建议。

相关内容