使用snmp4j获取服务器的cpu使用率、内存使用率的时候;需要找到对应的OID节点才能准确获取信息;请问  通过什么准确获取windows7下和Linux下的cpu、内存的OID节点? 紧急  紧急。

解决方案 »

  1.   

    楼主你好,在linux下采集基本没有问题,因为都是基于文件的,这些信息都可以从文件里面读出来;而windows平台下,内存的信息是比较容易获取的,而且准确,但cpu的信息就不大好处理了,一般是基于统计的方式,结果一般也不准确,因为统计的过程本身对cpu的使用也有影响。windows下还可以通过Jni的方式来获取cpu的信息,但是对环境的依赖太过明显。
        上面是可能遇到的一些问题,你说到的IOD是可以自定义的,服务端只要实现了对这些OID的处理就可以了。基本代码如下:public class CmsSnmpAgent {
    private static final Logger log = LoggerFactory.getLogger(CmsSnmpAgent.class);
    public final static String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";
    static int cpuNum = Runtime.getRuntime().availableProcessors();
    private Snmp snmp = null;
    /**
     * 初始化代理端口并添加处理逻辑
     * @author xiazhengyou 2011-10-9 上午09:49:41
     * @throws IOException
     */
    public void initComm(String cmsIpAddr, int snmpPort) throws IOException {
    // 设置Agent的IP和端口
    TransportMapping transport = new DefaultUdpTransportMapping(new UdpAddress(cmsIpAddr + "/" + snmpPort));
    snmp = new Snmp(transport);
    snmp.addCommandResponder(messageRec);
    transport.listen();
    }
    private static CommandResponder messageRec = new CommandResponder() {
    public synchronized void processPdu(CommandResponderEvent e) {
    // 接收message
    PDU command = e.getPDU();
    if ((command.getType() != PDU.TRAP) && (command.getType() != PDU.V1TRAP) && (command.getType() != PDU.REPORT) && (command.getType() != PDU.RESPONSE)) {
    command.setErrorIndex(0);
    command.setErrorStatus(0);
    command.setType(PDU.RESPONSE);
    log.debug("OID=" + command.get(0).getOid().toString());
    IMonitorService monitorService = new MonitorServiceImpl();
    MonitorInfoBean monitorInfoBean = monitorService.getMonitorInfoBean();
    log.debug("CPU:" + monitorInfoBean.getCpuRatio());
    log.debug("Thread:" + monitorInfoBean.getTotalThread());
    log.debug("memory:" + monitorInfoBean.getUsedMemory()); // 处理PDU
    for (int i = 0; i < command.size(); i++) {
    String oid = command.get(i).getOid().toString();
    /** cpu个数 **/
    if (oid.equals(Constants.HIK_CPU_NUM)) {
    command.get(i).setVariable(new Integer32(cpuNum));
    }
    /** 内存大小 **/
    else if (oid.equals(Constants.HIK_MEMORY_CAPABILITY)) {
    command.get(i).setVariable(new Integer32(monitorInfoBean.getTotolMemorySize()));
    }
    /** cpu使用率 **/
    else if (oid.equals(Constants.HIK_CPU_USAGE)) {
    command.get(i).setVariable(new Integer32((int)monitorInfoBean.getCpuRatio()));
    }
    /** 内存使用率 **/
    else if (oid.equals(Constants.HIK_MEMORY_USAGE)) {
    command.get(i).setVariable(new Integer32((int)monitorInfoBean.getUsedMemory()));
    }
    /** 线程数 **/
    else if (oid.equals(Constants.HIK_SERVER_THREADCOUNT)) {
    command.get(i).setVariable(new Integer32(monitorInfoBean.getTotalThread()));
    }
    /** 当前时间 **/
    else if (oid.equals(Constants.HIK_SERVER_CURTIME)) {
    command.get(i).setVariable(new OctetString(CommonUtil.convertCalendarToString(Calendar.getInstance(), DATE_FORMAT)));
    }
    /** 服务器描述 **/
    else if (oid.equals(Constants.HIK_SERVER_DESCRIBE)) {
    command.get(i).setVariable(new OctetString("cms_server"));
    }
    /** 服务器indexCode **/
    else if (oid.equals(Constants.HIK_SERVER_INDEXCODE)) {
    command.get(i).setVariable(new OctetString(AppConfig.getIndexCode()));
    }
    /** 服务器ip **/
    else if (oid.equals(Constants.HIK_SERVER_IP)) {
    command.get(i).setVariable(new OctetString(AppConfig.getCmsIpAddr()));
    }
    /** 服务器端口 **/
    else if (oid.equals(Constants.HIK_SERVER_PORT)) {
    command.get(i).setVariable(new Integer32(AppConfig.getListenPort()));
    }
    /** 服务器启动时间 **/
    else if (oid.equals(Constants.HIK_SERVER_STARTTIME)) {
    command.get(i).setVariable(new OctetString(System.getProperty("cmsStartTime")));
    }
    /** 服务器运行状态 **/
    else if (oid.equals(Constants.HIK_SERVER_STATE)) {
    command.get(i).setVariable(new Integer32(Integer.valueOf(System.getProperty("cmsState"))));
    }
    /** 服务器类型 **/
    else if (oid.equals(Constants.HIK_SERVER_TYPE)) {
    command.get(i).setVariable(new Integer32(1));
    }
    /** 服务器版本号 **/
    else if (oid.equals(Constants.HIK_SERVER_VERSION)) {
    command.get(i).setVariable(new OctetString(System.getProperty("cmsVersion")));
    }
    /** 服务器连接信息 **/
    else if (oid.equals(Constants.HIK_SERVER_CONNECTTABLE)) {
    // command.get(i).setVariable(new Integer32(2));
    }
    /** 默认响应 **/
    else {
    command.get(i).setVariable(new OctetString("No such oid"));
    }
    }
    StatusInformation statusInformation = new StatusInformation();
    StateReference ref = e.getStateReference();
    try {
    log.debug("send Response!");
    e.getMessageDispatcher().returnResponsePdu(e.getMessageProcessingModel(), e.getSecurityModel(), e.getSecurityName(), e.getSecurityLevel(), command, e.getMaxSizeResponsePDU(),
            ref, statusInformation);
    } catch (MessageException ex) {
    log.error(LogHelper.buildLogInfo(Business.PLATFORM_BASE, Model.PLATFORM_INIT, ErrorCode.CMS_INTERNAL_EXCEPTION, "初始化CMS的SnmpAgent异常", ex));
    }
    }
    }
    };
    /**
     * 启动监听
     * @author xiazhengyou 2011-10-9 上午09:49:20
     */
    public synchronized void start() {
    log.debug("CmsSnmpAgent has started, waiting for messages...");
    try {
    do {
    this.wait();// Wait for traps to come in
    } while (true);
    } catch (InterruptedException ex) {
    log.error(LogHelper.buildLogInfo(Business.PLATFORM_BASE, Model.PLATFORM_INIT, ErrorCode.CMS_INTERNAL_EXCEPTION, "启动CMS的SnmpAgent的监听异常", ex));
    }
    }
    /****
     * 测试方法
     * @author xiazhengyou 2011-10-9 上午09:43:02
     * @param args
     */
    public static void main(String[] args) {
    SnmpAgentThread thread = new SnmpAgentThread();
    thread.init("172.7.28.12", 6602);
    thread.start();
    }
    }采集cpu、内存和线程信息:
    public class MonitorServiceImpl implements IMonitorService {
    private static final Logger log = LoggerFactory.getLogger(MonitorServiceImpl.class);
    private static final int PERCENT = 100;
    // 物理总内存,单位MB
    private static int totolMemorySize = getTotalMemorySize();
    @Override
    public MonitorInfoBean getMonitorInfoBean() {
    MonitorInfoBean infoBean = new MonitorInfoBean();
    // 操作系统
    String osName = System.getProperty("os.name");
    // 获得线程总数
    ThreadGroup parentThread;
    for (parentThread = Thread.currentThread().getThreadGroup(); parentThread.getParent() != null; parentThread = parentThread.getParent());
    int totalThread = parentThread.activeCount();
    int pid = getServicePID();
    log.debug("getMonitorInfoBean PID is " + pid);
    double cpuRatio = 0;
    long usedMemory = 0L;
    if (osName.toLowerCase(Constants.locale).startsWith("windows")) {
    cpuRatio = CpuStatusJni.getCpuUsage(pid);
    log.debug("usedMem:" + CmsServerInfoUtil.getProcessMemUsed(pid) / (long)1024);
    usedMemory = CmsServerInfoUtil.getProcessMemUsed(pid) / (long)1024;
    } else {
    int[] result = getCpuAndMemRateForLinux(pid);
    cpuRatio = result[0];
    usedMemory = result[1] * totolMemorySize / (long)PERCENT;

    }
    // 构造返回对象
    infoBean.setTotalThread(totalThread);
    infoBean.setUsedMemory(usedMemory);
    infoBean.setCpuRatio(cpuRatio);
    infoBean.setTotolMemorySize(totolMemorySize);
    return infoBean;
    }
    /**
     * 获取服务器物理内存大小
     * @author xiazhengyou 2011-10-10 下午03:48:35
     * @return
     */
    private static int getTotalMemorySize() {
    OperatingSystemMXBean osmxb = (OperatingSystemMXBean)ManagementFactory.getOperatingSystemMXBean();
    return (int)(osmxb.getTotalPhysicalMemorySize() / (long)1024 / (long)1024);

    }

    /**
     * 获取当前应用程序所在进程的pid
     * @author xiazhengyou 2011-10-10 下午01:38:02
     * @return
     */
    private static int getServicePID() {
    int pid = -1;
    try {
    pid = Integer.valueOf(ManagementFactory.getRuntimeMXBean().getName().substring(0, ManagementFactory.getRuntimeMXBean().getName().indexOf("@")));
    } catch (NumberFormatException e) {
    log.error(LogHelper.buildLogInfo(Business.PLATFORM_BASE, Model.PLATFORM_PARAM_SEARCH, ErrorCode.CMS_INTERNAL_EXCEPTION, "获取当前应用程序所在进程的pid异常", e));
    }
    return pid;
    }

    /**
     * 根据进程pid获取该进程的cpu及mem使用率
     * @author xiazhengyou 2011-10-10 下午01:34:26
     * @param pid 进程pid
     * @return
     */
    private static int[] getCpuAndMemRateForLinux(int pid) {
    int[] result = {0, 0};
    InputStream is = null;
    InputStreamReader isr = null;
    BufferedReader brStat = null;
    StringTokenizer tokenStat = null;
    try {
    Process process = Runtime.getRuntime().exec("ps -o %cpu,%mem -p " + pid);
    is = process.getInputStream();
    isr = new InputStreamReader(is, Constants.GLOBAL_CHARSET);
    brStat = new BufferedReader(isr);
    if (brStat != null) {
    brStat.readLine();
    String temp = brStat.readLine();
    if (StringUtil.isNotEmpty(temp)) {
    tokenStat = new StringTokenizer(temp);
    String cpuUsage = tokenStat.nextToken();
    String memUsage = tokenStat.nextToken();
    log.debug("CpuUsage:" + cpuUsage);
    log.debug("memUsage:" + memUsage);
    // 四舍五入处理
    Float float1 = (Float.valueOf(cpuUsage) + 0.5f);
    Float float2 = (Float.valueOf(memUsage) + 0.5f);
    result[0] = Integer.valueOf(float1.intValue());
    result[1] = Integer.valueOf(float2.intValue());
    }
    }
    } catch (IOException ioe) {
                          //handle ioe
    } finally {
                          //做一些释放资源的操作
    }
    return result;
    }
    }window下我用到了封装的dll,但我的服务器都是部署到linux下的,这块基本没有继续维护了,因为维护由于平台差异而导致成本太大。点到为止,希望对你有帮助!!