昨天同事跟我说cacti突然抓不到一台服务器的snmp数据了,让我看看,然后就匆匆出去了。。登陆服务器后简单查看了下161端口开着,进程也没什么可疑的,就重启了snmpd服务,用
snmpwalk -v 2c -c public localhost .1.3.6.1.2.1.1.3
命令,发现已经可以抓取到数据了,本以为问题已经解决,谁知道刚过了10秒又出现同样的故障了。。运行 netstat -an|grep -w “161”,发现Recv-Q的数据有些异常,正常情况应该为0,现在却是86533,说明数据已经接收了,却一直处在等待接受的缓冲区。。初步怀疑是不是受到攻击,因为我们公司使用的共同体是默认的public,于是修改snmp的配置文件更改为pub,重启服务后发现又正常了,netstat -an|grep -w “161”,Recv-Q的数据也重新变为0了,测试也并未出现异常了。。
后来同事回来了,我问他做了什么修改,他说只是发现服务器上运行了并不需要的nfs服务,就把他停掉了。我把解决问题的过程告诉他,他说出现这个问题应该跟外部的攻击无关,可能还是内部的冲突引起的,于是我们又重新更改共同体为public,。发现问题又再次出现了。。。因为是停用nfs引起的故障所以肯定是跟nfs有关系,后来我们确认不需要nfs服务,卸载nfs问题解决。。
上网查资料,发现问题可能是“网络包分片导致的溢出”,以下是网上的资料写的:
当rsize/wsize大于网络的MTU(大部分网络都是1500,除非设置了支持大包)时,IP包在用UDP协议传输时会分片。大量IP包分片会消耗网络两端大量的CPU资源,而且还会导致网络通信更不稳定(因为完整的RPC在UDP分片的任何一个包丢失时都得整个RPC重传)。任何RPC的重传增加都会导致时延的增加。这是NFS over UDP性能的最大瓶颈。
如果你的网络拓扑很复杂,UDP的分片包的路由很可能不同,可能不会都及时到达服务器。内核对分片包的缓存有限制,最大值由ipfrag/_high_thresh指定。可以查看文件/proc/sys/net/ipv4/ipfrag_high_thresh和/proc/sys/net/ipv4/ipfrag_low_thresh。一旦未处理的包数目超过ipfrag_high_thresh,内核就会丢弃分片包,直到数量达到ipfrag_low_thresh
另一种监视的方法是文件/proc/net/snmp中的IP:ReasmFails。这是分片组合失败的数量,如果这个值在大量文件传输过程中上升太快,就有可能是有上述问题。
如果你在使用NFS客户端,你可能会想要监视IP重组失败的数量(内核重组包括网络碎片数据的数据包失败),可以通过SNMP变量IP-MIB::ipReasmFails实现,下面是一个简单的命令:
#snmpwalk localhost -c public IP-MIB::ipReasmFails.0 |
虽然最终问题解决了,但还有一个疑问就是为什么我更改了默认的public之后就会正常呢,看来还要再查查资料了。