第一句子网 - 唯美句子、句子迷、好句子大全
第一句子网 > java 通过snmp协议获取物理机CPU 内存容量及使用率 存储的容量及使用率

java 通过snmp协议获取物理机CPU 内存容量及使用率 存储的容量及使用率

时间:2021-03-26 09:00:49

相关推荐

java 通过snmp协议获取物理机CPU 内存容量及使用率 存储的容量及使用率

java 用snmp协议获取物理机CPU、内存容量及使用率,存储的容量及使用率,java获取trap告警

一、SNMP简介1、什么是snmp二、SNMP获取信息步骤1、开启SNMP2、MIB文件3、MIB浏览器三、java获取SNMP信息1、引入maven2、代码实现3、常用OID四、SNMPTRAP1、接收程序代码2、解析mib文件说明

一、SNMP简介

1、什么是snmp

snmp中文含义是简单网络管理协议,可用完成对计算机、路由器和其他网络设备的远程管理和监视。利用 SNMP 协议可以更好地管理和监控网络。管理工作站可以远程管理所有支持该协议的网络设备,如监视网络状态、修改网络设备配置、接收网络事件警告等。

通俗的讲: 我们可用通过snmp协议获取物理机、存储服务器、交换机等设备的信息,本文我们是通过java程序来获取。

二、SNMP获取信息步骤

1、开启SNMP

首先,我们需要在对应的设备上开启snmp协议,不同的设备可自行百度开启的方法。一般设备有对应的管理软件,可从管理软件开启snmp。

开启snmp需要注意两个地方:

1、开启时会让你设置团体名,一般填pulic就行。

2、端口默认162。

2、MIB文件

举例说明,获取任何一类设备信息,都需要该类设备对应的MIB文件,从MIB文件中解析出OID,每个OID对应一个指标。使用cpu核数对应的OID才能获取核数的个数。

注意:mib文件获取方式

1、打设备厂商客服电话获取。

2、去githup下载: mib链接,下载后不确定哪个MIB文件是我们需要的,只能用mib浏览器自己试呗。

3、MIB浏览器

mib浏览器就相当于一个客户端,用来解析mib文件,可以使用该浏览器模拟snmp请求获取对应的指标信息。

我是用浏览器先测试请求可不可用,然后在从浏览器上拿到oid用java程序获取。

点击进入mib浏览器下载地址

三、java获取SNMP信息

1、引入maven

<dependency><groupId>org.snmp4j</groupId><artifactId>snmp4j</artifactId><version>2.8.3</version></dependency>

2、代码实现

注:代码种有snmpGet、snmpWalk两个方法可用获取snmp信息。

snmpGet:是传入的哪个OID的值,就获取该OID的值。

snmpWalk:获取OID的子OID的值。举例说明,传入的OID是1.2.3.4。 获取的是1.2.3.4.1,1.2.3.4.2,1.2.3.4.3的OID值。

import lombok.extern.slf4j.Slf4j;import munityTarget;import org.snmp4j.PDU;import org.snmp4j.Snmp;import org.snmp4j.event.ResponseEvent;import org.snmp4j.mp.SnmpConstants;import org.snmp4j.smi.*;import org.snmp4j.transport.DefaultUdpTransportMapping;import org.snmp4j.util.DefaultPDUFactory;import org.snmp4j.util.TableEvent;import org.snmp4j.util.TableUtils;import java.io.IOException;import java.util.*;@Slf4jpublic class SnmpUtil2 {private static Snmp snmp = null;private static CommunityTarget target = null;private static Integer port = 162;private static String ip = "10.11.83.10";private static String communityName = "public";public static void main(String[] args) throws Exception {new SnmpUtil2(ip, port);List<TableEvent> tableEvents = snmpWalk("1.3.6.1.4.1..2.235.1.1.15.50.1.12");for (TableEvent tableEvent : tableEvents) {VariableBinding[] vb = tableEvent.getColumns();if (null == vb) {continue;}System.out.println(vb[0].getOid()+"======"+vb[0].getVariable());}log.info("=================美丽的分割线===================");ResponseEvent responseEvent = snmpGet("1.3.6.1.4.1..2.235.1.1.15.50.1.12");PDU response = responseEvent.getResponse();for (int i = 0; i < response.size(); i++) {VariableBinding vb1 = response.get(i);System.out.println(vb1.getOid().toString() + "===" + vb1.getVariable());}}public SnmpUtil2(String intranetDeviceIp, Integer snmpPort) throws IOException {if (snmp == null) {snmp = new Snmp(new DefaultUdpTransportMapping());snmp.listen();}//初始化CommunityTargettarget = new CommunityTarget();target.setCommunity(new OctetString(communityName));target.setVersion(SnmpConstants.version2c);target.setAddress(new UdpAddress(intranetDeviceIp + "/" + snmpPort));target.setTimeout(1000);target.setRetries(3);}private static ResponseEvent snmpGet(String oid) {PDU pdu = new PDU();pdu.addOID(new VariableBinding(new OID(oid)));ResponseEvent re = null;try {re = snmp.get(pdu, target);} catch (Exception e) {log.error("snmpGet 异常" + e.getMessage());}return re;}private static List<TableEvent> snmpWalk(String oid) {TableUtils utils = new TableUtils(snmp, new DefaultPDUFactory(PDU.GETBULK));OID[] columnOid = new OID[]{new OID(oid)};return utils.getTable(target, columnOid, null, null);}}

3、常用OID

用枚举的方式列了一些常用的OID,包括获取戴尔华为物理机CPU、内存容量及使用率,戴尔存储集群,FS8600,SCV3000,PS6210的容量及使用率

具体看下代码注释

public enum OidEnum {//物理机CPU总核数、使用率HostCpuUtilization("1.3.6.1.2.1.25.3.3.1.2","物理机CPU总核数和使用率","walk"),//物理机内存总量HostMemoryTotal("1.3.6.1.2.1.25.2.2.0","物理机内存总量","get"),//物理机内存总量(用来计算内存的使用率或者拿到硬盘总量)HostMemoryTotalCalUtil("1.3.6.1.2.1.25.2.3.1.5","物理机内存总量(用来计算内存的使用率或者拿到硬盘总量)","walk"),//物理机内存使用率(用来计算内存的使用率或者拿到硬盘使用量)HostMemoryUsedCalUtil("1.3.6.1.2.1.25.2.3.1.6","物理机内存使用率(用来计算内存的使用率或者拿到硬盘使用量)","walk"),/*** 华为物理机CPU总核数*/HuaWeiHostCpuTotal("1.3.6.1.4.1..2.235.1.1.15.50.1.12","华为物理机CPU总核数","walk"),/*** 华为物理机CPU使用率, 单位%*/HuaWeiHostCpuUtilization("1.3.6.1.4.1..2.235.1.1.1.23.0","华为物理机CPU使用率","get"),/*** 华为物理机内存总量*/HuaWeiHostMemoryTotal("1.3.6.1.4.1..2.235.1.1.16.50.1.4","华为物理机内存总量","walk"),/*** 华为物理机内存使用率, 单位%*/HuaWeiHostMemoryUtilization("1.3.6.1.4.1..2.235.1.1.1.25.0","华为物理机内存总量","get"),//scv3000获得存储总量StorageScv3000Total("1.3.6.1.4.1.674.11000.2000.500.1.2.32.1.3", "scv3000获得存储总量(单位GB)","walk"),StorageScv3000Alloc("1.3.6.1.4.1.674.11000.2000.500.1.2.32.1.7", "scv3000获得存储分配量(单位GB)","walk"),StorageScv3000Used("1.3.6.1.4.1.674.11000.2000.500.1.2.32.1.6", "scv3000获得存储使用量(单位GB)","walk"),//PS6210存储总量StoragePs6210Total("1.3.6.1.4.1.12740.1.1.2.1.1.1","PS6210存储总量(单位MB)","get"),//PS6210存储空闲量StoragePs6210Free("1.3.6.1.4.1.12740.1.1.2.1.15.1","PS6210存储空闲量(单位MB)","get"),//PS6210存储使用量StoragePs6210Used("1.3.6.1.4.1.12740.1.1.2.1.2.1","PS6210存储已使用(单位MB)","get"),//FS8600获得存储总量StorageFs8600Total("1.3.6.1.4.1.674.11000.2000.200.1.38.1","FS8600获得存储总量(单位MB)","get"),//FS8600获得存储使用量StorageFs8600Used("1.3.6.1.4.1.674.11000.2000.200.1.38.3","FS8600获得存储使用量(单位MB)","get"),//存储总量StorageClusterTotal("1.3.6.1.4.1.12124.1.3.1.0", "存储总量(从磁盘集群获取)","get"),//存储已使用量StorageClusterUsed("1.3.6.1.4.1.12124.1.3.2.0", "存储使用量(从磁盘集群获取)","get");private String oid;private String describe;private String type;OidEnum(String oid, String describe, String type) {this.oid = oid;this.describe = describe;this.type = type;}public String getOid() {return oid;}public String getdDscribe() {return describe;}}

四、SNMPTRAP

SNMP Trap是SNMP的一部分,当被监控段出现特定事件,可能是性能问题,甚至是网络设备接口宕掉等,代理端会给管理站发告警事件。通过告警事件,管理站可以通过定义好的方法来处理告警。

trap是主动把告警信息推送到一个监听了162端口的接收程序,接收程序接收到的告警是一个OID,我们需要对oid进行翻译成可读的告警信息,通过该OID去mib文件找到具体告警的详情描述。

比较难的是解析MIB文件,我写了个程序解析mib文件,发现有些文件解析不成功,也不知道为啥,去外网查了下,说是需要引入其他依赖的mib文件,不过我试了很多次还是不行。

1、接收程序代码

import java.io.IOException;import lombok.extern.slf4j.Slf4j;import mandResponder;import mandResponderEvent;import munityTarget;import org.snmp4j.MessageDispatcher;import org.snmp4j.MessageDispatcherImpl;import org.snmp4j.MessageException;import org.snmp4j.PDU;import org.snmp4j.Snmp;import org.snmp4j.log.LogFactory;import org.snmp4j.mp.MPv1;import org.snmp4j.mp.MPv2c;import org.snmp4j.mp.StateReference;import org.snmp4j.mp.StatusInformation;import org.snmp4j.security.Priv3DES;import org.snmp4j.security.SecurityProtocols;import org.snmp4j.smi.*;import org.snmp4j.tools.console.SnmpRequest;import org.snmp4j.transport.AbstractTransportMapping;import org.snmp4j.transport.DefaultTcpTransportMapping;import org.snmp4j.transport.DefaultUdpTransportMapping;import org.snmp4j.util.MultiThreadedMessageDispatcher;import org.snmp4j.util.ThreadPool;@Slf4jpublic class TrapReceiver implements CommandResponder {public TrapReceiver() {}public static void main(String[] args) {TrapReceiver snmp4jTrapReceiver = new TrapReceiver();try {snmp4jTrapReceiver.listen(new UdpAddress("10.11.26.219/162"));} catch (IOException e) {System.err.println("Error in Listening for Trap");System.err.println("Exception Message = " + e.getMessage());}}/*** This method will listen for traps and response pdu's from SNMP agent.*/public synchronized void listen(TransportIpAddress address) throws IOException {AbstractTransportMapping transport;if (address instanceof TcpAddress) {transport = new DefaultTcpTransportMapping((TcpAddress) address);} else {transport = new DefaultUdpTransportMapping((UdpAddress) address);}ThreadPool threadPool = ThreadPool.create("DispatcherPool", 10);MessageDispatcher mtDispatcher = new MultiThreadedMessageDispatcher(threadPool, new MessageDispatcherImpl());// add message processing modelsmtDispatcher.addMessageProcessingModel(new MPv1());mtDispatcher.addMessageProcessingModel(new MPv2c());// add all security protocolsSecurityProtocols.getInstance().addDefaultProtocols();SecurityProtocols.getInstance().addPrivacyProtocol(new Priv3DES());// Create TargetCommunityTarget target = new CommunityTarget();target.setCommunity(new OctetString("1q2w#E$R5t"));Snmp snmp = new Snmp(mtDispatcher, transport);snmp.addCommandResponder(this);transport.listen();System.out.println("Listening on " + address);try {this.wait();} catch (InterruptedException ex) {Thread.currentThread().interrupt();}}/*** This method will be called whenever a pdu is received on the given port* specified in the listen() method*/public synchronized void processPdu(CommandResponderEvent cmdRespEvent) {log.debug("Received PDU...");PDU pdu = cmdRespEvent.getPDU();System.out.println(cmdRespEvent.toString());System.out.println("接收到的trap信息:[发送来源="+cmdRespEvent.getPeerAddress()+",snmp版本="+"2"+",团体名="+"public"+", 携带的变量="+cmdRespEvent.getPDU().getVariableBindings()+"]");if (pdu != null) {for (int i = 0; i < pdu.size(); i++) {VariableBinding vb1 = pdu.get(i);//System.err.println(vb1.toString());}int pduType = pdu.getType();if ((pduType != PDU.TRAP) && (pduType != PDU.V1TRAP) && (pduType != PDU.REPORT)&& (pduType != PDU.RESPONSE)) {pdu.setErrorIndex(0);pdu.setErrorStatus(0);pdu.setType(PDU.RESPONSE);StatusInformation statusInformation = new StatusInformation();StateReference ref = cmdRespEvent.getStateReference();try {cmdRespEvent.getMessageDispatcher().returnResponsePdu(cmdRespEvent.getMessageProcessingModel(),cmdRespEvent.getSecurityModel(), cmdRespEvent.getSecurityName(),cmdRespEvent.getSecurityLevel(),pdu, cmdRespEvent.getMaxSizeResponsePDU(), ref, statusInformation);} catch (MessageException ex) {System.err.println("Error while sending response: " + ex.getMessage());LogFactory.getLogger(SnmpRequest.class).error(ex);}}}}}

2、解析mib文件说明

引入java的两个jar包,mibble-2.9.3.jar和mibble-mibs-2.9.3.jar,我解析时,遇到有的文件解析成功,有的解析报错。没有解析成功的,可用用笨方法,就是用mib浏览器查看oid,把所有的告警OID做成一个字典。

因没有实现成功,具体解析代码我就不贴了。

如果我有哪个地方写的不合适的地方,或者需要交流的可用加我qq:739749855

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。