从具有三个库的OID读取SNMP会产生不同的执行时间

问题描述 投票:0回答:1

我已经使用easysnmp读取SNMP OID,但我现在选择了pysnmp库,因为easysnmp不支持Python3中的asyncio archtecture。

考虑的问题是,pysnmp比其他库慢得多:

pysnmp:

from pysnmp.hlapi import *
import time

t = time.time()
iterator = getCmd(SnmpEngine(),
                  CommunityData('public'),
                  UdpTransportTarget(('192.168.1.120', 161)),
                  ContextData(),
                  ObjectType(ObjectIdentity("1.3.6.1.2.1.33.1.2.7.0")))

errorIndication, errorStatus, errorIndex, varBinds = next(iterator)

if errorIndication:  # SNMP engine errors
    print(errorIndication)
else:
    if errorStatus:  # SNMP agent errors
        print('%s at %s' % (
            errorStatus.prettyPrint(),
            varBinds[int(errorIndex)-1] if errorIndex else '?'))
    else:
        for varBind in varBinds:  # SNMP response contents
            print(' = '.join([x.prettyPrint() for x in varBind]))


print(time.time() - t, 's') 

日期:

SNMPv2-SMI::mib-2.33.1.2.7.0 = 21
0.15317177772521973 s

easysnmp

from easysnmp import snmp_get
import time

if __name__ == '__main__':
    t = time.time()
    response = snmp_get(
        '1.3.6.1.2.1.33.1.2.7.0', hostname='192.168.1.120',
        community='public', version=1
    )
    print(response.value)
    print(time.time() - t, 's')

日期:

21
0.0063724517822265625 s

gosnmp

func elapsed(what string) func() {
    start := time.Now()
    fmt.Println("start")
    return func() {
        fmt.Printf("%s took %v\n", what, time.Since(start))
    }
}

func snmpRead() {
    g.Default.Target = "192.168.1.120"
    err := g.Default.Connect()
    if err != nil {
        log.Fatalf("Connect() err: %v", err)
    }
    defer g.Default.Conn.Close()

    oids := []string{"1.3.6.1.2.1.33.1.2.7.0"}
    result, err2 := g.Default.Get(oids) // Get() accepts up to g.MAX_OIDS
    if err2 != nil {
        log.Fatalf("Get() err: %v", err2)
    }

    for i, variable := range result.Variables {
        fmt.Printf("%d: oid: %s ", i, variable.Name)

        switch variable.Type {
        case g.OctetString:
            fmt.Printf("string: %s\n", string(variable.Value.([]byte)))
        default:
            fmt.Printf("number: %d\n", g.ToBigInt(variable.Value))
        }
    }
}

func main() {
    defer elapsed("snmp")()
    snmpRead()
}

日期:

start
0: oid: .1.3.6.1.2.1.33.1.2.7.0 number: 21
snmp took 3.668148ms

pysnmp快30倍


我需要go-routine在Python3中填充asyncio的异步性能。

那么,这是否意味着我应该从pysnmp迁移到gosnmp

python snmp pysnmp easysnmp gosnmp
1个回答
0
投票

请记住,相对于后续调用,第一次pysnmp调用可能需要更多时间。由于惰性导入,索引,可能的MIB编译等。

因此,如果您的用例是从同一进程发出许多SNMP查询,我建议在测量所用时间时考虑到这一点。

另一件事是最新的(未发布的)pysnmp在低级SNMP例程中引入了asyncio绑定,即不包括SNMP引擎及其涉及的所有重型机器。

pysnmp.hlapi.v1arch.asyncio API旨在从其签名角度非常类似于pysnmp.hlapi.v3arch.asyncio,但它应该更快,但不以SNMPv3支持为代价。如果您需要,MIB支持仍然存在。

当您只导入pysnmp.hlapi.asyncio时,您将有效地获得pysnmp.hlapi.v3arch.asyncio,因此要使用v1arch,您需要明确导入它。

例如,下面的脚本(在GitHub master pysnmp下运行)可能会更快:

import asyncio
from pysnmp.hlapi.v1arch.asyncio import *


@asyncio.coroutine
def run():
    snmpDispatcher = SnmpDispatcher()

    iterator = getCmd(
        snmpDispatcher,
        CommunityData('public'),
        UdpTransportTarget(('192.168.1.120', 161)),
        ('1.3.6.1.2.1.33.1.2.7.0', None)
    )

    errorIndication, errorStatus, errorIndex, varBinds = yield from iterator

    if errorIndication:
        print(errorIndication)

    elif errorStatus:
        print('%s at %s' % (
            errorStatus.prettyPrint(),
            errorIndex and varBinds[int(errorIndex) - 1][0] or '?'
        )
              )
    else:
        for varBind in varBinds:
            print(' = '.join([x.prettyPrint() for x in varBind]))

    snmpDispatcher.transportDispatcher.closeDispatcher()


asyncio.get_event_loop().run_until_complete(run())
© www.soinside.com 2019 - 2024. All rights reserved.