我正在 Zabbix 的帮助下监控一台主机,我注意到 Zabbix 代理开始使用相当多的 CPU 周期:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
26774 zabbix 20 0 68428 1312 752 R 99 0.0 63:27.67 /usr/sbin/zabbix_agentd
26773 zabbix 20 0 68428 1324 764 R 99 0.0 63:26.33 /usr/sbin/zabbix_agentd
代理监控的项目大约有 100 个。它们也在 Zabbix 代理不消耗太多 CPU 的其他相同主机上进行监控。代理将收集的数据发送到 Zabbix 代理。代理配置为默认配置。主机 CPU 有 8 个核心(2.4 Gz)。监控项目的最小时间值为 60 秒。
我使用 Zabbix 服务器/代理 1.8.11,至少现在无法升级到 2.2。
我从各个方面检查了调试日志:Zabbix 服务器、代理、agent,没有发现任何问题。只是一直接收和发送常规检查。
我不知道如何进一步调查此问题并寻求社区帮助。我如何追踪代理为何如此消耗 CPU?
对我来说还有一件奇怪的事情是网络连接的统计信息:
netstat -an|awk '/tcp/ {print $6}'|sort|uniq -c
2 CLOSE_WAIT
21 CLOSING
3521 ESTABLISHED
2615 FIN_WAIT1
671 FIN_WAIT2
1542 LAST_ACK
14 LISTEN
256 SYN_RECV
117841 TIME_WAIT
谢谢。
更新 1。
netstat -tnp|grep zabbix
tcp 1 0 10.120.0.3:10050 10.128.0.15:53372 CLOSE_WAIT 23777/zabbix_agentd
tcp 1 0 10.120.0.3:10050 10.128.0.15:53970 CLOSE_WAIT 23775/zabbix_agentd
tcp 1 0 10.120.0.3:10050 10.128.0.15:53111 CLOSE_WAIT 23776/zabbix_agentd
10.128.0.15 - Zabbix 服务器的 IP 10.120.0.3 - Zabbix 主机的 IP
更新 2。
这些 TIME_WAIT 连接来自 Web 服务器 nginx。
更新 3。
我使用 strace 附加到 Zabbix 代理进程,发现 100% 被以下代理使用read syscall
:
strace -C -f -p 23776
Process 23776 detached
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
100.00 2.175528 2515 865 read
------ ----------- ----------- --------- --------- ----------------
100.00 2.175528 865 total
更新 4。
为了让所有事情都清楚...我尝试使用 TIME_WAIT 连接状态。例如,我尝试减少net.ipv4.netfilter.ip_conntrack_tcp_timeout_time_wait
并net.netfilter.nf_conntrack_tcp_timeout_time_wait
查看是否有帮助。不幸的是,它没有帮助。
结论
Zabbix 代理 CPU 负载问题似乎与网络连接数有关。如果我们使用 strace 连接到 zabbix_agentd 进程,我们将看到 CPU 周期的使用情况(第一列 - 在内核中运行所花费的 CPU 时间):
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
100.00 15.252232 8646 1764 read
0.00 0.000000 0 3 write
0.00 0.000000 0 1 open
...
------ ----------- ----------- --------- --------- ----------------
100.00 15.252232 1778 total
这里大部分 CPU 时间都用在了读取系统调用上。进一步调查显示,这些读取调用(下面显示了其中 2 个)是连续尝试读取文件/proc/net/tcp
。后者包含网络统计信息,例如 TCP 和 UDP 连接、套接字等。平均而言,文件包含 70000-150000 个条目。
8048 0.000068 open("/proc/net/tcp", O_RDONLY) = 7 <0.000066>
8048 0.000117 fstat(7, {st_dev=makedev(0, 3), st_ino=4026531993, st_mode=S_IFREG|0444, st_nlink=1, st_uid=0, st_gid=0, st_blksize=1024, st_blocks=0, st_size=0, st_atime=2013/04/01-09:33:57, st_mtime=2013/04/01-09:33:57, st_ctime=2013/04/01-09:33:57}) = 0 <0.000012>
8048 0.000093 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f30a0d38000 <0.000033>
8048 0.000087 read(7, " sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode "..., 1024) = 1024 <0.000091>
8048 0.000170 read(7, " \n 6: 0300810A:0050 9275CE75:E67D 03 00000000:00000000 01:00000047 0000000"..., 1024) = 1024 <0.000063>
答案1
我认为瓶颈是光盘。以下是我的理由:
您的 Web 服务器非常繁忙。Zabbix 很慢,我怀疑是从磁盘读取的(也可能是从网络读取的)。
再次运行 strace,并在 Zabbix 中找到文件描述符
然后检查文件描述符是文件还是套接字:
ls -l /prod/<PID_of_straced_process>/fd/<FD_from_strace>
编辑1:
您不应该更改 TIME_WAIT 超时。小型 HTTP 保持活动或没有 HTTP 保持活动的问题在于您会增加延迟和带宽。相反,您应该稍微增加 HTTP 保持活动并安装/启用 SPDY。
编辑2:使用dstat -ta 10
并将第一行与其余行进行比较。第一行是自启动以来的平均值。接下来的几行是 10 秒平均值(最后一个参数)。
编辑3:检查您是否没有丢失数据包,使用类似 smokeping 的工具从网络外部监控服务器和网站。您有大量处于 CLOSING、FIN_WAIT1、FIN_WAIT2、SYN_RECV、LAST_ACK 状态的连接。我认为您的网络拥塞或您有很多短暂的连接(由较高的 TIME_WAIT/ESTABILISHED 比率确认)。请参阅:http://en.wikipedia.org/wiki/Transmission_Control_Protocol#Protocol_operation
答案2
zabbix-agentd 每个 net.tcp.listen 项读取 /proc/net/tcp。文件大小约为 100K(行) * 150 字节 = 15MB,如果您有许多 tcp.listen 监控项,则此读取文件操作将消耗大量 CPU,因为数据大小为 15MB*item_number。
为了解决此性能问题,建议使用 net.tcp.port 而不是 net.tcp.listen。
答案3
迟来的回答(可能对某些人有帮助):
这种情况经常发生,取决于您对 Zabbix 的请求,通常是第三方问题或 PEBKAC。
禁用检查(然后重新启动 zabbix 服务器)以查看哪个检查导致负载过重。据此分析问题。
比如,我在使用数据库监视器时遇到了几个问题,都是由 ODBC 引起的