0

我正在开发一个需要显示 CPU 使用率以及远程机器的其他系统信息的项目。人们建议使用 SIGAR 来实现这一点,但我不知道如何使用它。源代码对我来说不太有意义。基本上,我的问题是:如何在提供主机 IP 和 JMX 端口时将 SIGAR 提供的 MBean 注册到服务器,以及之后如何从其他计算机获取系统信息。如果我对 JMX 的工作方式有误,请纠正我。提前致谢。

4

3 回答 3

0

在我看来,您将不得不编写一些包装对象以将各种 SIGAR 输出公开为 JMX mbean 属性。您如何做到这一点在很大程度上取决于您使用什么来公开您的 JMX bean。我将为各种不同类型的 SIGAR 输出中的每一种编写一个包装对象:内存、磁盘、...

我编写了一个SimpleJMX 库,可能会有所帮助。我将使用它的格式提供一个示例对象,您可以使用它通过 JMX 公开信息。您可以将其调整为用于发布 JMX 的任何机制。我对 SIGAR 不够熟悉,无法知道我下面的 sigar 代码是否正确获取ProcMem实例。

@JmxResource(description = "Show SIGAR Info", domainName = "foo")
public class SigarProcMem {

    private ProcMem procMem;

    {
      // sorry, I'm not up on sigar so I'm not sure if this works
      Sigar sigar = new Sigar();
      procMem = sigar.getProcMem(sigar.getPid());
    }

    @JmxAttributeMethod(description = "Resident memory")
    public long residentMemory() {
       return procMem.getResident();
    }

    @JmxAttributeMethod(description = "Get the Total process virtual memory")
    public long totalVirtualMemory() {
       return procMem.getSize();
    }
}
于 2012-06-11T17:48:14.160 回答
0

这些是您可以注册的 Sigar 内置 MBean 的类的名称:

  • org.hyperic.sigar.jmx.SigarCpu
  • org.hyperic.sigar.jmx.SigarCpuInfo
  • org.hyperic.sigar.jmx.SigarCpuPerc
  • org.hyperic.sigar.jmx.SigarLoadAverage
  • org.hyperic.sigar.jmx.SigarMem
  • org.hyperic.sigar.jmx.SigarProcess
  • org.hyperic.sigar.jmx.SigarRegistry
  • org.hyperic.sigar.jmx.SigarSwap

但是,远程部署这些将非常复杂,因为 Sigar 依赖于本地库,当加载 MBean 时,该库必须位于目标 JVM 的 lib-path 中。这意味着,您需要在要监控的每个目标主机上主动加载库和 MBean。

您可能能够破解一种通过远程调用使目标 JVM 加载它的方法,但这并不重要,并且需要您绕过 JVM 中的任何安全设置,因为默认情况下,这是您不应该做的能够做到。

于 2012-06-11T21:13:03.290 回答
0

您可以通过破解系统部分来轻松部署 Sigjar:

private String before;
private Sigar sigar;

/**
 * Constructor - don't forget to call unload later!
 */
public SetlogSigar() throws Exception {
    before = System.getProperty("java.library.path");

    String path = "";

    String add = getJarFolder();

    if (before.contains(";"))
        path = before + ";./;" + add;
    else
        path = before + ":./:" + add;

    setSystemPath(path);

    sigar = new Sigar();

}

/**
 * This is needed to dynamically update the JAVA Path environment in order to load the needed native library
 * Yes -rather an ugly hack...
 */
private String getJarFolder() {
    // get name and path
    String path = SetlogSigar.class.getProtectionDomain().getCodeSource().getLocation().getPath();
    String decodedPath = path;
    try {
        decodedPath = URLDecoder.decode(path, "UTF-8");
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
        return null;
    }    

    File f = new File(decodedPath);
    String absolutePath = f.getParentFile().getParentFile().getParentFile().getParent()+"/lib";

    return absolutePath;
}

/**
 * Unloads the JNI bindings
 */
public void unload() {
    this.sigar.close();
    setSystemPath(before);
}

此 hack 将 sigjar.jar 所在的文件夹动态添加到环境变量中。只需将所有本机库放在那里,部署就会变得不那么复杂。

于 2013-07-24T16:02:54.573 回答