如果我通过 SNMP 轮询,例如 Cisco IOS 接口ifHCInOctets
计数器并且上次读数低于先前读数,那么我知道设备已重新加载,ifHCInOctets
计数器已回绕,存在影响此特定接口的在线硬件插入/移除 (OIR)或者接口被删除并重新创建(这在 VLAN 接口、端口通道接口等情况下是可能的)。现在我想区分路由器重新加载和ifHCInOctets
从零开始的所有其他可能性。起初snmpEngineTime
(根据 Cisco SNMP 对象导航器的范围为 0 - 2147483647)似乎是一个完美的解决方案,因为这个计数器在 68 年后回绕,但如果 SNMP 代理重新启动,它也会从零开始,即停止(no snmp-server
)和启动(snmp-server community public RO
)。这意味着仍然需要检查sysUpTime
,据我所知,只有在系统重新启动的情况下才从零开始,但不幸的是每 497 天后换行。这意味着如果sysUpTime
在ifHCInOctets
变为零时在相同检查之间换行,则下面看到的简单算法将不起作用:
if (( prev_ifHCInOctets > cur_ifHCInOctets )); then
if (( prev_sysUpTime > cur_sysUpTime )); then
echo "router reloaded"
else
echo "counter wrapped, OIR or interface recreated"
fi
fi
如果有“ sysUpHCTime
”计数器就完美了,但看起来没有。我有哪些选择?我想一种可能性是简单地忽略这种极不可能的情况,其中cur_ifHCInOctets
(ifHCInOctets
计数器的当前读数)和cur_sysUpTime
(sysUpTime
计数器的当前读数)都小于以前的读数,因为两个计数器都包含在相同的轮询间隔内。但是,出于兴趣,这里有什么选择?我想至少一种可能的选择不是检查 if prev_sysUpTime > cur_sysUpTime
,而是检查prev_sysUpTime
和之间的增量cur_sysUpTime
是否大致相当于脚本检查间隔?我的意思是,例如让我们想象一个prev_sysUpTime
变量是 42949500 并且脚本知道它在 300 秒前获得这个值的情况。现在cur_sysUpTime
脚本读取的是 128。作为下一步,脚本检查cur_sysUpTime
+(42949672- prev_sysUpTime
) 是否在 300 左右(例如在 295 - 305 范围内),如果是,则 100% 确定sysUpTime
从零开始,因为计数器换行和不是因为设备重新加载。这个公式中使用的42949672是在sysUpTime
不包括毫秒的情况下SNMP计数器的最大值,即SNMP的最大值sysUpTime
是2^32,但最后两位数字代表毫秒,例如4294967296是42949672秒(约497天)和96毫秒。
很抱歉这篇很长的帖子,如果有任何不清楚的地方,请告诉我。