Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/370.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代码设置JMX远程端口系统环境参数进行远程监控?_Java_Rmi_Jmx - Fatal编程技术网

如何通过java代码设置JMX远程端口系统环境参数进行远程监控?

如何通过java代码设置JMX远程端口系统环境参数进行远程监控?,java,rmi,jmx,Java,Rmi,Jmx,我有一个程序,它需要动态(即在运行时)打开一个可用的套接字并在其上启动JMX代理。这个JMX参数是在Java代码内部设置的,而不是通过命令行设置的。这个很好用。此后,需要通过Java Visual VM进行监视(即发出JMX命令等) 遥远地 程序中的RMI服务器代理处于开箱即用管理的线路上,如所述: 我的问题可以概括为: 如何将此类命令行属性设置为系统级 通过Java代码,使远程评测可以使用 -Dcom.sun.management.jmxremote.port=1234 如果通过命令行设置

我有一个程序,它需要动态(即在运行时)打开一个可用的套接字并在其上启动JMX代理。这个JMX参数是在Java代码内部设置的,而不是通过命令行设置的。这个很好用。此后,需要通过Java Visual VM进行监视(即发出JMX命令等) 遥远地

程序中的RMI服务器代理处于开箱即用管理的线路上,如所述:

我的问题可以概括为: 如何将此类命令行属性设置为系统级 通过Java代码,使远程评测可以使用

-Dcom.sun.management.jmxremote.port=1234
如果通过命令行设置“jmxremote.port”等参数, 远程监控工作正常。我正试图找到一种通过Java实现这一点的方法 而不是通过命令行

程序无法通过命令行指定端口,因为必须在运行时计算出新的可用端口

该过程需要远程监控,并且在本地运行良好。 如果在命令行中未指定以下参数,则Java Visual VM不会连接到进程

-Dcom.sun.management.jmxremote.port=1234
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Djava.rmi.server.hostname=10.0.0.128
我试过了

System.setProperty("com.sun.management.jmxremote.port",Integer.toString(port));
这是启动JMXConnectorServer之前程序中首先要做的事情之一。不幸的是,它没有得到承认。Java Visual VM只能识别JMX连接的运行时属性(即通过命令行指定的属性)

还遇到了从java集合类中提取属性的方法,但无法找到如何跟踪属性“com.sun.management.jmxremote.port=”

publicstaticvoidsetenv(Map newenv)引发异常{
Class[]classes=Collections.Class.getDeclaredClasses();
Map env=System.getenv();
对于(类别cl:类别){
if(“java.util.Collections$UnmodifiableMap”.equals(cl.getName())){
字段字段=cl.getDeclaredField(“m”);
字段。setAccessible(true);
Object obj=field.get(env);
Map Map=(Map)obj;
//map.clear();
普塔尔地图(新环境);
}
}
}

任何帮助都将不胜感激

System.setProperty()
-D
命令行选项相同。但是,显然您必须尽早调用它,以便在读取属性之前设置属性。

如果未将任何
jmxremote
env指定为run参数,则未加载JMX管理代理。对于动态加载,您可以尝试以下方法:

public static String loadJMXAgent(int port) throws IOException, AttachNotSupportedException, AgentLoadException, AgentInitializationException {
    System.setProperty("com.sun.management.jmxremote.port", Integer.toString(port));
    String name = ManagementFactory.getRuntimeMXBean().getName();
    VirtualMachine vm = VirtualMachine.attach(name.substring(0, name.indexOf('@')));

    String lca = vm.getAgentProperties().getProperty("com.sun.management.jmxremote.localConnectorAddress");
    if (lca == null) {
        Path p = Paths.get(System.getProperty("java.home")).normalize();
        if (!"jre".equals(p.getName(p.getNameCount()-1).toString().toLowerCase())) p = p.resolve("jre");
        File f = p.resolve("lib").resolve("management-agent.jar").toFile();
        if (!f.exists()) throw new IOException("Management agent not found");

        vm.loadAgent(f.getCanonicalPath(), "com.sun.management.jmxremote");
        lca = vm.getAgentProperties().getProperty("com.sun.management.jmxremote.localConnectorAddress");
    }
    vm.detach();
    return lca;
}

您必须包括
jdk/lib/tools.jar

kbec的答案为我指明了方向,但并不适用于我-但是通过查看,我能够修改它并获得一个有效的解决方案

public static String loadJMXAgent(int port) throws IOException,
        AttachNotSupportedException, AgentLoadException,
        AgentInitializationException {
    String name = ManagementFactory.getRuntimeMXBean().getName();
    VirtualMachine vm = VirtualMachine.attach(name.substring(0,
            name.indexOf('@')));

    String lca = vm.getAgentProperties().getProperty(
            "com.sun.management.jmxremote.localConnectorAddress");
    if (lca == null) {
        Path p = Paths.get(System.getProperty("java.home")).normalize();
        if (!"jre".equals(p.getName(p.getNameCount() - 1).toString()
                .toLowerCase())) {
            p = p.resolve("jre");
        }
        File f = p.resolve("lib").resolve("management-agent.jar").toFile();
        if (!f.exists()) {
            throw new IOException("Management agent not found");
        }
        String options = String.format("com.sun.management.jmxremote.port=%d, " +
                "com.sun.management.jmxremote.authenticate=false, " +
                "com.sun.management.jmxremote.ssl=false", port);
        vm.loadAgent(f.getCanonicalPath(), options);
        lca = vm.getAgentProperties().getProperty(
                "com.sun.management.jmxremote.localConnectorAddress");
    }
    vm.detach();
    return lca;
}
这在Eclipse中是可行的,但是让它在命令行上工作是另一回事——这里有一些关于这方面的讨论
但是我发现在我的类路径中添加$JAVA_HOME/lib/tools.jar解决了这个问题

我尝试了一些方法,从java代码中指定jmxremote端口,以便在特定端口上建立连接,并得出以下结论:

如果指定了jmxremote参数: 在我的代码修改必要的jmxremote System.properties之前,JVM启动平台mbean服务器。每个mbean服务器都有自己的bean注册表。plaform和JVM MBean无法以另一种方式向它注册自己的bean

设置jmx端口属性后,可以创建备用mbean服务器。将在您指定的正确jmx端口上侦听

通过这种方式,您可以选择平台服务器:

MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
这样你自己的

System.setProperty("com.sun.management.jmxremote.port","9991");
//...
MBeanServer mbsCustom=MBeanServerFactory.createMBeanServer();

还考虑Linux有“强>环回接口< /强>,因此您应该明确指定正确的主机名以侦听。


根据手册,不建议使用平台以外的其他MBeanServer,但我可以想象,在某些情况下,命令行选项不是启动服务器的方式。

这对我来说是可行的。参考资料。我假设您已经知道如何纠正下面示例中使用的SimpleXbean

package sample;

import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.rmi.registry.LocateRegistry;
import java.util.HashMap;
import java.util.Map;

import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;

public class MBServerTest {
    public static void loadJMXAgent(int port, MBeanServer mbs) throws IOException  {
        LocateRegistry.createRegistry(port);
        System.out.println("Initialize the environment map");
        Map<String,Object> env = new HashMap<String,Object>();
        env.put("com.sun.management.jmxremote.authenticate", "false");
        env.put("com.sun.management.jmxremote.ssl", "false");
        System.out.println("Create an RMI connector server");
        JMXServiceURL url =
            new JMXServiceURL("service:jmx:rmi:///jndi/rmi://:"+port+"/jmxrmi");
        JMXConnectorServer cs =
            JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs);

        // Start the RMI connector server.
        //
        System.out.println("Start the RMI connector server");
        cs.start();

    }

    public static void main(String[] args) throws Exception {
        MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
        loadJMXAgent(1199,mbs);

        SimpleStandard cache = new SimpleStandard();

        ObjectName name = new ObjectName(
                "org.javalobby.tnt.jmx:type=ApplicationCacheMBean");
        mbs.registerMBean(cache, name);
        imitateActivity(cache);
    }

    private static void imitateActivity(SimpleStandard cache) {
        while (true) {
            try {
                cache.cacheObject("hello");
                Thread.sleep(1000);
            } catch (InterruptedException e) {
            }
        }
    }
}
包装样品;
导入java.io.IOException;
导入java.lang.management.ManagementFactory;
导入java.rmi.registry.LocateRegistry;
导入java.util.HashMap;
导入java.util.Map;
导入javax.management.MBeanServer;
导入javax.management.ObjectName;
导入javax.management.remote.JMXConnectorServer;
导入javax.management.remote.JMXConnectorServerFactory;
导入javax.management.remote.JMXServiceURL;
公共类MBServerTest{
公共静态void loadJMXAgent(int端口,MBeanServer mbs)引发IOException{
LocateRegistry.createRegistry(端口);
System.out.println(“初始化环境映射”);
Map env=new HashMap();
put(“com.sun.management.jmxremote.authenticate”、“false”);
put(“com.sun.management.jmxremote.ssl”,“false”);
System.out.println(“创建RMI连接器服务器”);
JMXServiceURL=
新的JMXServiceURL(“服务:jmx:rmi:///jndi/rmi://:“+端口+”/jmxrmi”);
JMXconnectorServerCS=
newJMXConnectorServer(url、env、mbs);
//启动RMI连接器服务器。
//
System.out.println(“启动RMI连接器服务器”);
cs.start();
}
公共静态void main(字符串[]args)引发异常{
MBeanServer mbs=ManagementFactory.getPlatformMBeanServer();
loadJMXAgent(1199,mbs);
SimpleStandard缓存=新的SimpleStandard();
ObjectName=新的ObjectName(
“org.javalobby.tnt.jmx:type=ApplicationCacheMBean”);
registerMBean(缓存,名称);
模仿性(cache);
}
私有静态void模拟活动(SimpleStandard缓存){
while(true){
试一试{
cache.cacheObject(“hello”);
睡眠(1000);
}捕捉(中断异常e){
}
}
}
}
package sample;

import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.rmi.registry.LocateRegistry;
import java.util.HashMap;
import java.util.Map;

import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;

public class MBServerTest {
    public static void loadJMXAgent(int port, MBeanServer mbs) throws IOException  {
        LocateRegistry.createRegistry(port);
        System.out.println("Initialize the environment map");
        Map<String,Object> env = new HashMap<String,Object>();
        env.put("com.sun.management.jmxremote.authenticate", "false");
        env.put("com.sun.management.jmxremote.ssl", "false");
        System.out.println("Create an RMI connector server");
        JMXServiceURL url =
            new JMXServiceURL("service:jmx:rmi:///jndi/rmi://:"+port+"/jmxrmi");
        JMXConnectorServer cs =
            JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs);

        // Start the RMI connector server.
        //
        System.out.println("Start the RMI connector server");
        cs.start();

    }

    public static void main(String[] args) throws Exception {
        MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
        loadJMXAgent(1199,mbs);

        SimpleStandard cache = new SimpleStandard();

        ObjectName name = new ObjectName(
                "org.javalobby.tnt.jmx:type=ApplicationCacheMBean");
        mbs.registerMBean(cache, name);
        imitateActivity(cache);
    }

    private static void imitateActivity(SimpleStandard cache) {
        while (true) {
            try {
                cache.cacheObject("hello");
                Thread.sleep(1000);
            } catch (InterruptedException e) {
            }
        }
    }
}
private void createJmxConnectorServer() throws IOException {
    LocateRegistry.createRegistry(1234);
    MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
    JMXServiceURL url = new JMXServiceURL("service:jmx:rmi://localhost/jndi/rmi://localhost:1234/jmxrmi");
    JMXConnectorServer svr = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);
    svr.start();
}