0

我已经习惯easysnmp阅读 SNMP OID,但我pysnmp现在选择了库,因为easysnmp不支持Python3asyncio中的架构。

考虑的问题是,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

简单的snmp

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

快 30 倍于pysnmp


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

那么,这是否意味着我应该从 迁移pysnmpgosnmp

4

1 回答 1

0

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

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

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

pysnmp.hlapi.v1arch.asyncioAPI 旨在pysnmp.hlapi.v3arch.asyncio与其签名观点非常相似,但它应该更快,但代价是不支持 SNMPv3。如果您需要,MIB 支持仍然存在。

当您导入 justpysnmp.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())
于 2019-02-25T15:18:15.640 回答