• snmpwalk高延时问题分析


    问题出现

    有两台物理机,一台是192.168.1.15,另一台是192.168.1.43。二者的netsnmp版本相同。

    使用snmpwalk去访问两台机器,获取tcp重传数(tcpRetransSegs)时,192.168.1.43回复时间非常长。多达140s+,但是相同配置的192.168.1.15只需要30ms。

    -bash-4.1# time snmpwalk -v 2C  -c cluster -t 200 -r 0 192.168.1.15 .1.3.6.1.2.1.6.12
    TCP-MIB::tcpRetransSegs.0 = Counter32: 2364728
    
    real	0m0.030s
    user	0m0.020s
    sys	0m0.003s
    
    -bash-4.1# time snmpwalk -v 2C  -c cluster -t 200 -r 0 192.168.1.43 .1.3.6.1.2.1.6.12
    TCP-MIB::tcpRetransSegs.0 = Counter32: 3771986491
    
    real	2m27.554s
    user	0m0.020s
    sys	0m0.003s
    

    这个现象非常奇怪,按理说tcpRetransSegs是从/proc/net/snmp中直接拿数据然后解析,耗时应该非常短。不应该到秒级。
    而且在使用time snmpwalk -v 2C -c cluster -t 200 -r 0 192.168.1.43 .1.3.6.1.2.1.6.12进行访问时,是立即返回了TCP-MIB::tcpRetransSegs.0 = Counter32: 3771986491的信息,但是接着卡住长达140s+,然后该命令才结束。
    说明返回tcpRetransSegs的数据并没有消耗多少时间,但是之后未知的流程导致了巨大时间的消耗。

    问题分析

    对比了两台机器,发现二者最大的区别在于192.168.1.15上有较少的连接数,大概10+。而192.168.1.43上有多达4000+的连接数。

    尝试只用snmpget来获取192.168.1.43tcpRetransSegs的值

    -bash-4.1#  time snmpget -v 2C  -c cluster -t 200 -r 0 192.168.1.43 .1.3.6.1.2.1.6.12.0
    TCP-MIB::tcpRetransSegs.0 = Counter32: 3850778646
    
    real	0m0.025s
    user	0m0.023s
    sys	0m0.002s
    

    可以发现立即返回,而使用snmpwalk依然耗时巨大。

    snmpwalk

    snmpwalk是遍历mib上的某棵子树,包含了至少两个动作,get和getnext。

    首先对于oid进行get操作,然后进行getnext,获取返回值和名称(oid)。
    然后判断该返回的oid是否还在这个子树上,如果不在了,那么就结束。
    如果还在该子树上,则使用返回的oid继续getnext,直到结束。

    具体来说,就是time snmpwalk -v 2C -c cluster -t 200 -r 0 192.168.1.43 .1.3.6.1.2.1.6.12命令可以分为以下几部分:

    首先对oid.1.3.6.1.2.1.6.12进行get。

    -bash-4.1# time snmpget -v 2C  -c cluster -t 200 -r 0 192.168.1.43 .1.3.6.1.2.1.6.12
    TCP-MIB::tcpRetransSegs = No Such Instance currently exists at this OID
    
    real	0m0.025s
    user	0m0.019s
    sys	0m0.001s
    

    然后进行getnext

    -bash-4.1# time snmpgetnext -v 2C  -c cluster -t 200 -r 0 192.168.1.43 .1.3.6.1.2.1.6.12
    TCP-MIB::tcpRetransSegs.0 = Counter32: 3815361069
    
    real	0m0.025s
    user	0m0.022s
    sys	0m0.001s
    

    因为返回的tcpRetransSegs.0.1.3.6.1.2.1.6.12树上,因此继续getnext

    -bash-4.1# time snmpgetnext -v 2C  -c cluster -t 200 -r 0 192.168.1.43 .1.3.6.1.2.1.6.12.0
    TCP-MIB::tcpConnState.0.0.0.0.22.0.0.0.0.0 = INTEGER: listen(2)
    
    real	2m20.125s
    user	0m0.022s
    sys	0m0.002s
    

    这次返回的tcpConnState.0.0.0.0.22.0.0.0.0.0已经出了.1.3.6.1.2.1.6.12树,因此snmpwalk结束。
    这里也可以看到主要的耗时就是在这一步上了。而这一步耗时的主要原因是获取tcpConnState需要将所有的连接遍历一遍。
    这也与观察到的192.168.1.43上连接数高相吻合。

    结论

    time snmpwalk -v 2C -c cluster -t 200 -r 0 192.168.1.43 .1.3.6.1.2.1.6.12耗时巨大的主要原因是错用了snmpwalk。导致去获取tcpConnState的数据,从而致使snmpd在分析所有的连接时,耗费了巨大的时间和CPU资源。

    正确的方法应该是使用snmpget -v 2C -c cluster -t 200 -r 0 192.168.1.43 .1.3.6.1.2.1.6.12.0去获取数据。

    这里也有一个教训,就是如果能够准确回去的oid数据,最好使用get,使用getnext会降低其效率。

  • 相关阅读:
    在Android studio中,测试输出数组中最大子数组的和
    我所理解的软件开发模式
    java实现随机输出300题四则运算
    Demo(3月28日)
    关于构建之法中小飞问题的个人看法
    对搭档代码的一些意见
    项目复审
    安卓UI测试(基于android studio环境 espresso框架)
    读构建之法后的一些个人感受
    思考题
  • 原文地址:https://www.cnblogs.com/xuxinkun/p/5590272.html
Copyright © 2020-2023  润新知