刮取多个单一和分支OID的最有效方法是什么?

2024-05-14 06:31:03 发布

您现在位置:Python中文网/ 问答频道 /正文

我总是处于最高速度和最小资源消耗之间的战争,所以我的目标是找到速度和资源消耗的最佳组合。
对于每个snmp设备,我希望扫描多个分支下的OID。
每个分支下都有动态数量的OID,因此我不知道我需要什么特定的OID,我只知道我需要一个分支下的所有OID。
我有一些设备只支持SNMPv1,因此我为这些设备编写与SNMPv1兼容的代码。
对于其他设备,我使用SNMPv2。在

SNMPv1

假设我有两个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编写2asyncNextCmd

^{pr2}$

我不太了解SNMP,但我认为第二个代码有一些缺点。
例如,在一些客户机上,我有数百个SNMP设备,因此我同时为每个网络设备打开了一个asyncCmd
这导致大量设备无响应,CPU使用率过高。在

SNMPv2

我还想了解批量是如何工作的,以及是否可以使用它来提高代码的效率。
假设我有两个树枝,我想走。
1.3.6.1.2.1.4.20有5个OID,1.3.6.1.2.1.4.21有39个OID。
我得到了两个分支中的所有值,但我也得到了比我想要的更多的值。
我得到的值总是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的最有效方法是什么?在


Tags: 代码数量分支publicoidstrsnmpv1errorindication
2条回答

首先要认识到的是,您不能指示SNMP代理精确地返回一个“分支”。SNMP(协议级别)不支持此类操作。经理可以控制请求哪些OID以及何时停止。代理可以一次返回精确的单个OID(GET)或下一个OID(GETNEXT/GETBULK)或大约数量的下一个OID(GETBULK)。在

如果您有动态OID,您无法可靠地预测在任何给定时刻有多少个OID。因此,我不认为您可以严格地在一个SNMP操作中获得分支oid。在

我说过你应该尽可能使用GETBULK。目标是在一个GETBULK操作中获取它们的最大预期数量。但是请检查您的代码,您确实得到了所有的东西(代理可能不会一次返回所请求数量的oid)。在

至于您正在使用的pysnmpapi,为了停止它的GETBULK/GETNEXT迭代,您应该从回调函数返回True。您可以分析从代理那里获得的oid,并在它们超出您感兴趣的分支时返回True。这将终止一个分支检索,其他分支将继续运行。在

对于不同的oid,向同一SNMP代理发送多个并行查询的设计显然效率要低得多。在

您想要bulkCmd,如中所述

http://pysnmp.sourceforge.net/examples/current/v3arch/oneliner/manager/cmdgen/getbulk-v2c.html

它将从网络设备中以更少和更大的块来获取数据。在

相关问题 更多 >