使用gosnmp发起snmpwalk请求29秒后超时的原因及相关问题咨询
测试日志如下:
{"Elapsed Time":28596.288132,"time":"2021-10-11T18:24:14-04:00","message":"testSnmpWalk succeeded"} {"error":"request timeout (after 0 retries)","Elapsed Time":29571.202639,"time":"2021-10-11T18:43:37-04:00","message":"testSnmpWalk failed"} {"Elapsed Time":14645.645597,"time":"2021-10-11T18:44:40-04:00","message":"testSnmpWalk succeeded"}
问题1解答
是的,SNMP Walk的底层实现是连续发送GetNext请求,每次请求获取前缀范围内的下一个OID值,直到返回的OID超出指定遍历范围才终止。
你日志中出现的request timeout (after 0 retries)说明某一次GetNext请求发出后,在你配置的单次请求超时时间内未收到设备响应,且你未配置重试次数,因此直接触发了整个Walk任务的失败。三次测试耗时波动大也符合这一特征:部分GetNext请求响应慢就会拉长整体耗时,极端情况就会触发超时。
问题2解答
可以通过两个维度区分两种场景:
- 先做网络连通性校验:在发起SNMP请求前先对目标设备发起ICMP Ping探测,如果Ping丢包率高于30%、平均延迟波动极大或者完全不通,属于设备不可达/网络故障场景,适合配置更短的SNMP超时,快速失败避免资源占用。
- 单条简单SNMP请求校验:如果Ping连通性正常,单独发送针对轻量系统OID(例如
1.3.6.1.2.1.1.1.0,设备描述OID)的Get请求,如果该请求响应慢、经常超时,说明设备SNMP Agent进程被高负载阻塞,属于设备繁忙导致请求失败场景,适合调长超时时间。
问题3解答
gosnmp原生的Walk/BulkWalk方法的重试逻辑为:仅重试当前超时失败的那条GetNext/GetBulk请求,之前已经成功拉取的OID数据不会重复请求,不需要担心超时后要从头遍历。
如果你是自行封装的Walk逻辑,且没有记录当前已经遍历到的OID游标,超时后直接重新发起全量Walk,才会出现全量重试的情况。标准net-snmp的snmpwalk命令的重试逻辑和gosnmp原生逻辑一致。
问题4解答
首先纠正你的推测:gosnmp是纯Go语言实现的原生SNMP协议库,没有封装系统的net-snmp命令行工具,所有协议逻辑都是独立实现的。
不过参数对应关系是对的:
- gosnmp的
Retries字段对应net-snmp命令行的-r参数,含义为单次请求超时后的重试次数 - gosnmp的
Timeout字段对应net-snmp命令行的-t参数,含义为单次请求的最大等待时间,区别是gosnmp的Timeout是time.Duration类型,需要显式指定时间单位,net-snmp的-t默认单位为秒。
内容的提问来源于stack exchange,提问作者toddw
相关产品推荐
相关产品推荐

