Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/384.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用SIGAR远程获取另一台机器的系统信息?_Java_Jmx_Sigar - Fatal编程技术网

Java 如何使用SIGAR远程获取另一台机器的系统信息?

Java 如何使用SIGAR远程获取另一台机器的系统信息?,java,jmx,sigar,Java,Jmx,Sigar,我正在做一个项目,需要显示远程机器的CPU使用情况以及其他系统信息。 人们建议使用SIGAR来实现这一点,但我不知道如何使用它。源代码对我来说没有什么意义。 基本上,我的问题是:在提供主机IP和JMX端口的情况下,如何将SIGAR提供的MBean注册到服务器,以及如何从其他计算机获取系统信息。 如果我对JMX的工作方式有错误,请纠正我。提前感谢。在我看来,您必须编写一些包装对象,以将各种SIGAR输出作为JMX mbean属性公开。如何做到这一点在很大程度上取决于使用什么来公开JMX bean。

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

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

我写了一篇可能有用的文章。我将使用它的格式提供一个示例对象,您可以使用它通过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();
    }
}

以下是可以注册的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 然而,远程部署这些将非常复杂,因为加载MBean时,Sigar依赖于本机库,而本机库必须位于目标JVM的lib路径中。这意味着您需要在要监视的每个目标主机上主动加载库和MBean


您可能可以通过远程调用破解一种让目标JVM加载此文件的方法,但这不是一件小事,需要您绕过JVM中的任何安全设置,因为默认情况下,这是您不应该做的事情。

您可以对系统部分进行某种破解,以便轻松部署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);
}

这种黑客动态地将sigjar.jar所在的文件夹添加到环境变量中。只需将所有本机lib放在其中,部署就不那么复杂了。

nifty library。我们在我工作的地方实现了一个类似的库。想知道为什么要粉碎JmxOperation注释中的参数信息,而不是为参数创建单独的注释吗?@jtahlborn-Heh。我只是讨厌这件事的复杂性。我总是要查找如何创建注释字段数组或复制另一个实例。我用得不够多,记不住-我想你误解我了。我指的是有一个单独的注释,你把它放在方法参数上,不涉及数组。我认为这比JmxOperation中的值数组简单得多。@jtahlborn哦,对了。这件事很少做,我都忘了。不太确定。我猜混合使用参数和注释可能会损害可读性。我会将其添加到待办事项列表中进行调查。不确定这是否是我真正想要的。也许我的问题只是暴露MBean的过程。