【问题标题】:A weird problem about parallel , concurrent SNMP requests by SNMP4j V3一个关于 SNMP4j V3 并行并发 SNMP 请求的奇怪问题
【发布时间】:2019-01-15 08:10:18
【问题描述】:

我使用版本 3 USM 模型通过 SNMP4J 发送 SNMP 请求。但是当我发送 SNMP 请求 concureent IP1,IP2 没有问题收到一切正常我收到两个响应 PDU。此外,当我尝试发送 IP1、IP3 evertyhing 正常时,我成功接收到响应,但是当我同时尝试 IP2、IP3 时,IP3 请求总是失败,我收到的响应 PDU 为空。 谁能告诉我是什么问题?

并发IP1,IP2没问题收到一切正常。 并发IP1,IP3没问题收到一切正常。 并发IP2、IP3有问题。 IP3 响应 PDU 始终为空。

public class SnmpFetcher {

    static byte[] localEngineID = MPv3.createLocalEngineID();

    static{

        USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(localEngineID), 0);

        SecurityModels.getInstance().addSecurityModel(usm);
    }

    private Logger logger = Logger.getLogger(SnmpFetcher.class);

    private Target target = null;
    private SnmpAgentConfig snmpAgentConfig = null;
    private TransportMapping<? extends Address> transport = null;
    private Snmp snmp = null;

    long startTime = System.currentTimeMillis();

    public SnmpFetcher(SnmpTarget snmpTarget) {

        target = snmpTarget.getTarget();

        snmpAgentConfig = snmpTarget.getSnmpAgentConfig();
    }

    public void start() throws AgentException {

        try {
            transport = new DefaultUdpTransportMapping();

            snmp = new Snmp(transport);     

            createAuth(snmpAgentConfig, snmp);

            logger.debug("SNMP Agent : " + target.getAddress() + " added security info ");

            transport.listen();

            logger.debug("SNMP Agent : " + target.getAddress() + " UDP transport is listenening ");

        } catch (Exception e) {
            throw new AgentException(e);
        }

    }

    public void stop() throws AgentException {
        if (snmp != null) {
            try {
                snmp.close();
            } catch (IOException e) {
                throw new AgentException(e);
            }
        }
    }

    private void createAuth(SnmpAgentConfig snmpAgentConfig, Snmp snmp) {
        if (snmpAgentConfig instanceof SnmpAgentConfig_v3) {

            SnmpAgentConfig_v3 snmpAgentConfig_v3 = (SnmpAgentConfig_v3) snmpAgentConfig;

            OctetString username = new OctetString(snmpAgentConfig_v3.getUsername());
            OID authProtocol = snmpAgentConfig_v3.getAuthProtocol();
            OctetString authPassword = new OctetString(snmpAgentConfig_v3.getAuthPassword());
            OID privProtocol = null;
            OctetString privPassword = null;

            if (snmpAgentConfig_v3.getPrivProtocol() != null) {
                privProtocol = snmpAgentConfig_v3.getPrivProtocol();
            }

            if (snmpAgentConfig_v3.getPrivPassword() != null) {
                privPassword = new OctetString(snmpAgentConfig_v3.getPrivPassword());
            }

            logger.debug("SNMP Agent : " + target.getAddress() + " localEngineID : " + new OctetString(localEngineID));

            snmp.setLocalEngine(localEngineID, 0, 0);

            UsmUser usmUser = new UsmUser(username, authProtocol, authPassword, privProtocol, privPassword);

            snmp.getUSM().addUser(username, usmUser);

        }
    }

    private DefaultPDUFactory createPDU(int pduType, Target target, SnmpAgentConfig_v3 snmpAgentConfig, String context) {

        SnmpAgentConfig_v3 snmpAgentConfig_v3 = (SnmpAgentConfig_v3) snmpAgentConfig;

        OctetString contextName = null;

        if (context != null) {
            contextName = new OctetString(context);
        } else {
            contextName = new OctetString();
        }

        OctetString contextEngineID = null;

        if (snmpAgentConfig_v3.getContextAgentId() != null) {
            contextEngineID = new OctetString(snmpAgentConfig_v3.getContextAgentId());
        } else {
            contextEngineID = new OctetString();
        }

        return new DefaultPDUFactory(pduType, contextEngineID, contextName);

    }

    private DefaultPDUFactory createPDU(int pduType, Target target) {
        return new DefaultPDUFactory(pduType);
    }

    public Map<String, SNMPValue> doWalk(String oid) throws AgentException {

        logger.debug("SNMP Agent : " + snmpAgentConfig.getLoopbackip() + " SNMP " + "WALK" + " is started for OID : " + oid);

        Map<String, SNMPValue> result = new TreeMap<String, SNMPValue>();

        try {

            start();

            DefaultPDUFactory defaultPDUFactory = createPDU(PDU.GETNEXT, target);

            PDU pdu = defaultPDUFactory.createPDU(target);
            pdu.setRequestID(new Integer32(SNMPRequestIdHandler.getNextRequestId()));

            TreeUtils treeUtils = new TreeUtils(snmp, defaultPDUFactory);
            List<TreeEvent> events = treeUtils.getSubtree(target, new OID(oid));

            if (events == null || events.size() == 0) {
                logger.error("SNMP Agent : " + target.getAddress() + " Error: No result returned, table OID [" + oid + "] ");
                return result;
            }

            for (TreeEvent event : events) {
                if (event == null) {
                    continue;
                }
                if (event.isError()) {
                    logger.error("SNMP Agent : " + target.getAddress() + " Error: table OID [" + oid + "]  Error Status : " + event.getErrorMessage());
                    continue;
                }

                VariableBinding[] varBindings = event.getVariableBindings();
                if (varBindings == null || varBindings.length == 0) {
                    continue;
                }
                for (VariableBinding varBinding : varBindings) {
                    if (varBinding == null) {
                        continue;
                    }

                    result.put("." + varBinding.getOid().toString(), new SNMPValue(varBinding));
                }

            }

        } catch (Exception e) {

            long endTime = System.currentTimeMillis();
            long timeToRun = endTime - startTime;
            logger.error("SNMP Agent : " + snmpAgentConfig.getLoopbackip() + " SNMP " + "WALK" + " is failed for OID : " + oid + " , Execution Time : " + timeToRun);
            throw new AgentException(e);
        } finally {
            stop();
        }

        long endTime = System.currentTimeMillis();
        long timeToRun = endTime - startTime;

        logger.debug("SNMP Agent : " + snmpAgentConfig.getLoopbackip() + " SNMP " + "WALK" + " is finished for OID : " + oid + " , Record Count : " + result.size() + ", Execution Time : " + timeToRun);

        return result;
    }

    public Map<String, SNMPValue> doWalk(String oid, String context) throws AgentException {

        logger.debug("SNMP Agent : " + snmpAgentConfig.getLoopbackip() + " SNMP " + "WALK" + " is started for OID : " + oid);

        Map<String, SNMPValue> result = new TreeMap<String, SNMPValue>();

        try {

            start();

            DefaultPDUFactory defaultPDUFactory = createPDU(PDU.GETNEXT, target, (SnmpAgentConfig_v3) snmpAgentConfig, context);

            PDU pdu = defaultPDUFactory.createPDU(target);
            pdu.setRequestID(new Integer32(SNMPRequestIdHandler.getNextRequestId()));

            TreeUtils treeUtils = new TreeUtils(snmp, defaultPDUFactory);
            List<TreeEvent> events = treeUtils.getSubtree(target, new OID(oid));

            if (events == null || events.size() == 0) {
                logger.error("SNMP Agent : " + target.getAddress() + " Error: No result returned, table OID [" + oid + "] , Context : " + context);
                return result;
            }

            for (TreeEvent event : events) {
                if (event == null) {
                    continue;
                }
                if (event.isError()) {
                    logger.error("SNMP Agent : " + target.getAddress() + " Error: table OID [" + oid + "] , Context : " + context + " Error Status : " + event.getErrorMessage());
                    continue;
                }

                VariableBinding[] varBindings = event.getVariableBindings();
                if (varBindings == null || varBindings.length == 0) {
                    continue;
                }
                for (VariableBinding varBinding : varBindings) {
                    if (varBinding == null) {
                        continue;
                    }

                    result.put("." + varBinding.getOid().toString(), new SNMPValue(varBinding));
                }

            }

        } catch (Exception e) {

            long endTime = System.currentTimeMillis();
            long timeToRun = endTime - startTime;
            logger.error("SNMP Agent : " + snmpAgentConfig.getLoopbackip() + " SNMP " + "WALK" + " is failed for OID : " + oid + " , Context : " + context + ", Execution Time : " + timeToRun);
            throw new AgentException(e);
        } finally {
            stop();
        }

        long endTime = System.currentTimeMillis();
        long timeToRun = endTime - startTime;

        logger.debug("SNMP Agent : " + snmpAgentConfig.getLoopbackip() + " SNMP " + "WALK" + " is finished for OID : " + oid + " , Context : " + context + ", Record Count : " + result.size() + ", Execution Time : " + timeToRun);

        return result;
    }

    public SNMPValue get(String oid) throws AgentException {

        logger.debug("SNMP Agent : " + snmpAgentConfig.getLoopbackip() + " SNMP " + "GET" + " is started for OID : " + oid);

        long startTime = System.currentTimeMillis();

        SNMPValue result = null;

        try {

            start();

            DefaultPDUFactory defaultPDUFactory = createPDU(PDU.GET, target);

            PDU pdu = defaultPDUFactory.createPDU(target);

            pdu.add(new VariableBinding(new OID(oid)));
            pdu.setRequestID(new Integer32(SNMPRequestIdHandler.getNextRequestId()));

            logger.debug("SNMP Agent : " + target.getAddress() + " OID [" + oid + "] , PDU Request Id : " + pdu.getRequestID());

            ResponseEvent response = snmp.send(pdu, target, transport);

            // Process Agent Response
            if (response != null) {
                PDU responsePDU = response.getResponse();


                if (response.getError() != null) {
                    logger.info("SNMP Agent : " + target.getAddress() + " Response Error : " + response.getError());
                    response.getError().printStackTrace();
                }

                if (responsePDU != null) {
                    logger.debug("SNMP Agent : " + target.getAddress() + " OID [" + oid + "] , PDU Response Id : " + responsePDU.getRequestID());

                    int errorStatus = responsePDU.getErrorStatus();
                    int errorIndex = responsePDU.getErrorIndex();
                    String errorStatusText = responsePDU.getErrorStatusText();

                    if (errorStatus == PDU.noError) {
                        if (responsePDU.getVariableBindings() != null && responsePDU.getVariableBindings().size() > 0) {
                            result = new SNMPValue(responsePDU.getVariableBindings().get(0));
                        } else {
                            logger.error("SNMP Agent : " + target.getAddress() + " Error: Empty or null  OID [" + oid + "] ");
                        }
                    } else {
                        logger.error("SNMP Agent : " + target.getAddress() + " Error: Request Failed.  OID [" + oid + "] , Error Status : " + errorStatus);
                        throw new AgentException("SNMP Agent : " + target.getAddress() + " Error: Request Failed.  OID [" + oid + "] , Error Status : " + errorStatus);
                    }
                } else {
                    logger.error("SNMP Agent : " + target.getAddress() + " Error: Response PDU is null  OID [" + oid + "] ");
                    throw new AgentException("SNMP Agent : " + target.getAddress() + " Error: Response PDU is null  OID [" + oid + "] ");
                }
            } else {
                logger.error("SNMP Agent : " + target.getAddress() + " Error: Agent Timeout.  OID [" + oid + "] ");
                throw new AgentException("SNMP Agent : " + target.getAddress() + " Error: Agent Timeout.  OID [" + oid + "] ");
            }

        } catch (IOException e) {
            long endTime = System.currentTimeMillis();
            long timeToRun = endTime - startTime;
            logger.error("SNMP Agent : " + snmpAgentConfig.getLoopbackip() + " SNMP " + "GET" + " is failed for OID : " + oid + " , Execution Time : " + timeToRun);
            throw new AgentException(e);
        } finally {
            stop();
        }

        long endTime = System.currentTimeMillis();
        long timeToRun = endTime - startTime;

        if (result != null) {
            logger.debug("SNMP Agent : " + snmpAgentConfig.getLoopbackip() + " SNMP " + "GET" + " is finished for OID : " + oid + " , Record Count : " + 1 + ", Execution Time : " + timeToRun);
        } else {
            logger.debug("SNMP Agent : " + snmpAgentConfig.getLoopbackip() + " SNMP " + "GET" + " is finished for OID : " + oid + " , Record Count : " + 0 + ", Execution Time : " + timeToRun);
        }

        return result;
    }

    public SNMPValue get(String oid, String context) throws AgentException {

        logger.debug("SNMP Agent : " + snmpAgentConfig.getLoopbackip() + " SNMP " + "GET" + " is started for OID : " + oid);

        long startTime = System.currentTimeMillis();

        SNMPValue result = null;

        try {

            start();

            DefaultPDUFactory defaultPDUFactory = createPDU(PDU.GET, target, (SnmpAgentConfig_v3) snmpAgentConfig, context);

            PDU pdu = defaultPDUFactory.createPDU(target);

            pdu.add(new VariableBinding(new OID(oid)));
            pdu.setRequestID(new Integer32(SNMPRequestIdHandler.getNextRequestId()));

            logger.debug("SNMP Agent : " + target.getAddress() + " OID [" + oid + "] , Context : " + context + ", PDU Request Id : " + pdu.getRequestID());

            ResponseEvent response = snmp.send(pdu, target, transport);

            // Process Agent Response
            if (response != null) {
                PDU responsePDU = response.getResponse();

                if (response.getError() != null) {
                    logger.info("SNMP Agent : " + target.getAddress() + " Response Error : " + response.getError() + " , Context : " + context);
                    response.getError().printStackTrace();
                }

                if (responsePDU != null) {
                    logger.debug("SNMP Agent : " + target.getAddress() + " OID [" + oid + "] , Context : " + context + ", PDU Response Id : " + responsePDU.getRequestID());

                    int errorStatus = responsePDU.getErrorStatus();
                    int errorIndex = responsePDU.getErrorIndex();
                    String errorStatusText = responsePDU.getErrorStatusText();

                    if (errorStatus == PDU.noError) {
                        if (responsePDU.getVariableBindings() != null && responsePDU.getVariableBindings().size() > 0) {
                            result = new SNMPValue(responsePDU.getVariableBindings().get(0));
                        } else {
                            logger.error("SNMP Agent : " + target.getAddress() + " Error: Empty or null  OID [" + oid + "] , Context : " + context);
                        }
                    } else {
                        logger.error("SNMP Agent : " + target.getAddress() + " Error: Request Failed.  OID [" + oid + "] , Context : " + context + ", Error Status : " + errorStatus);
                        throw new AgentException("SNMP Agent : " + target.getAddress() + " Error: Request Failed.  OID [" + oid + "] , Context : " + context + ", Error Status : " + errorStatus);
                    }
                } else {
                    logger.error("SNMP Agent : " + target.getAddress() + " Error: Response PDU is null  OID [" + oid + "] , Context : " + context);
                    throw new AgentException("SNMP Agent : " + target.getAddress() + " Error: Response PDU is null  OID [" + oid + "] , Context : " + context);
                }
            } else {
                logger.error("SNMP Agent : " + target.getAddress() + " Error: Agent Timeout.  OID [" + oid + "] , Context : " + context);
                throw new AgentException("SNMP Agent : " + target.getAddress() + " Error: Agent Timeout.  OID [" + oid + "] , Context : " + context);
            }

        } catch (IOException e) {
            long endTime = System.currentTimeMillis();
            long timeToRun = endTime - startTime;
            logger.error("SNMP Agent : " + snmpAgentConfig.getLoopbackip() + " SNMP " + "GET" + " is failed for OID : " + oid + " , Context : " + context + ", Execution Time : " + timeToRun);
            throw new AgentException(e);
        } finally {
            stop();
        }

        long endTime = System.currentTimeMillis();
        long timeToRun = endTime - startTime;

        if (result != null) {
            logger.debug("SNMP Agent : " + snmpAgentConfig.getLoopbackip() + " SNMP " + "GET" + " is finished for OID : " + oid + " , Context : " + context + ", Record Count : " + 1 + ", Execution Time : " + timeToRun);
        } else {
            logger.debug("SNMP Agent : " + snmpAgentConfig.getLoopbackip() + " SNMP " + "GET" + " is finished for OID : " + oid + " , Context : " + context + ", Record Count : " + 0 + ", Execution Time : " + timeToRun);
        }

        return result;
    }

}

------------

IP2

new Thread(){

run{
     SNMPValue data = snmpFetcher.get(oid);
}


IP3

new Thread(){

run{

     SNMPValue data = snmpFetcher.get(oid);
}

【问题讨论】:

  • SNMP 代理:/161 错误:响应 PDU 为空 OID [.1.3.6.1.2.1.1.1.0]
  • SNMP 代理 : /161 成功

标签: java snmp4j


【解决方案1】:

我找到了解决方案。两个或多个主机的 snmp 代理上下文 id 相同。 当使它们独一无二时,一切正常。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-06-17
    • 1970-01-01
    • 1970-01-01
    • 2019-05-12
    • 1970-01-01
    • 2020-10-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多