我总是处于最大速度和最小资源消耗之间的战争,因此我的目标是找到速度和资源消耗的最佳组合。
对于每个snmp设备,我想扫描几个分支下的oid
每个分支都有动态数量的oid,所以我不知道我需要什么特定的oid,我只知道我需要一个分支下的所有oid。
我有一些设备只支持SNMPv1,所以对于那些设备,我编写了与SNMPv1兼容的代码
对于其他设备,我使用SNMPv2。
假设我有两个OID,我想走他们的branch('1.3.6.1.2.1.4' and '1.3.6.1.2.1.6')
分支OID是指分支下的所有OID
我有以下代码:
cmdGen = cmdgen.AsynCommandGenerator()
cmdGen.asyncNextCmd(
cmdgen.CommunityData('public', mpModel=1),
cmdgen.UdpTransportTarget(('192.168.0.101', 161)),
(str('1.3.6.1.2.1.4'),str('1.3.6.1.2.1.6'),),
(__cbFun_Walk, (cmdgen.CommunityData('public', mpModel=1), cmdgen.UdpTransportTarget(('192.168.0.101', 161)))))
cmdGen.snmpEngine.transportDispatcher.runDispatcher()
这很有效,但唯一的问题是我只能一次性停止所有步行,因此我不能单独停止每次步行,所以一旦最长的步行结束,所有步行都将完成。
显然这是低效的
我还可以为分支OID编写2 asyncNextCmd
:
cmdGen = cmdgen.AsynCommandGenerator()
cmdGen.asyncNextCmd(
cmdgen.CommunityData('public', mpModel=1),
cmdgen.UdpTransportTarget(('192.168.0.101', 161)),
(str('1.3.6.1.2.1.4'),),
(__cbFun_Walk, (cmdgen.CommunityData('public', mpModel=1),
cmdgen.UdpTransportTarget(('192.168.0.101', 161)))))
cmdGen.asyncNextCmd(
cmdgen.CommunityData('public', mpModel=1),
cmdgen.UdpTransportTarget(('192.168.0.101', 161)),
(str('1.3.6.1.2.1.6'),),
(__cbFun_Walk, (cmdgen.CommunityData('public', mpModel=1),
cmdgen.UdpTransportTarget(('192.168.0.101', 161)))))
cmdGen.snmpEngine.transportDispatcher.runDispatcher()
我不太了解SNMP,但我认为第二个代码有一些缺点
例如,在某些客户端上,我有数百个SNMP设备,因此我同时为每个网络设备打开了asyncCmd
这导致了许多无响应的设备和过高的CPU使用率。
我还想尝试了解批量的工作方式,以及是否可以使用它来提高我的代码效率
可以说我有2个分支,我想走路
1.3.6.1.2.1.4.20有5个oids,1.3.6.1.2.1.4.21有39个oids。
我得到了两个分支中的所有值,但我也得到了更多的值,然后我也想要
我获得的值总是具有最高oid数量的分支乘以我拥有的分支数量
例如,具有最多oid的分支具有39个oid,并且分支的数量是2,因此39 * 2 = 78,这意味着getBulk将返回78个oid。
我希望getBulk返回每个分支的所有分支oid而不是更多,所以在我的情况下我想要44个oid(39 + 5 = 44)。
这是我的代码:
cmdGen = cmdgen.CommandGenerator()
errorIndication, errorStatus, errorIndex, varBindTable = cmdGen.bulkCmd(
cmdgen.CommunityData('public'),
cmdgen.UdpTransportTarget(('192.168.0.101', 161)),
0, 1,
'1.3.6.1.2.1.4.21', '1.3.6.1.2.1.4.20'
)
if errorIndication:
print errorIndication
elif errorStatus:
print '%s at %s\n' % (
errorStatus.prettyPrint(),
errorIndex and varBindTable[-1][int(errorIndex)-1] or '?'
)
else:
for varBindTableRow in varBindTable:
for name, val in varBindTableRow:
print str(name.prettyPrint()) + ' = ' + str(val.prettyPrint())
那么为SNMPv1和SNMPv2抓取多个分支OID的最有效方法是什么?
答案 0 :(得分:1)
首先要意识到的是,您无法指示SNMP代理返回正确的分支"。 SNMP(协议级别)不支持此类操作。管理者可以控制要求的OID和何时停止。代理可以一次返回确切的单个OID(GET)或下一个OID(GETNEXT / GETBULK)或下一个OID的大概数量(GETBULK)。
如果您有动态OID,则无法在任何给定时刻可靠地预测其中有多少OID。因此,我不认为您可以在单个SNMP操作中严格获得分支OID。
话虽如此,我认为你应尽可能尝试使用GETBULK。瞄准最大预期的OID数量,以便在一次GETBULK操作中获取它们。但请检查您的代码,确实可以获得所有内容(代理可能不会同时返回所请求的OID数量)。
对于您正在使用的pysnmp API,要停止其GETBULK / GETNEXT迭代,您应该从回调函数返回True。您可以分析从代理处获得的OID,并在超出您感兴趣的分支时返回True。这将终止一个分支检索,其余将继续运行。
为不同的OID发送多个并行查询到同一SNMP代理的设计效率明显低得多。
答案 1 :(得分:0)
您想要{/ 1}},如
所述http://pysnmp.sourceforge.net/examples/current/v3arch/oneliner/manager/cmdgen/getbulk-v2c.html
它将以更少和更大的块从网络设备返回数据。