JMX Server Behind Firewall

来源:互联网 发布:照片拼图软件 编辑:程序博客网 时间:2024/05/18 18:53

http://blog.sunchangming.com/post/47188405466

JMX Server Behind Firewall

本来JMX用起来很简单

mBeanServer = ManagementFactory.getPlatformMBeanServer();

Object obj=new MyMbean();

mBeanServer.registerMBean(obj, new ObjectName(“com.tianshen:type=xiyou,name=”+obj.getClass().getCanonicalName()));

但是JMX在远程使用的时候经常不大好使。

JMX remote最基本的用法是,在启动的时候加上

-Dcom.sun.management.jmxremote 
-Dcom.sun.management.jmxremote.authenticate=true 
-Dcom.sun.management.jmxremote.password.file=jmxpass 
-Dcom.sun.management.jmxremote.port=13000 
-Dcom.sun.management.jmxremote.ssl=false

下面解释下com.sun.management.jmxremote.port这个东西。默认情况下,JMX协议是架构在RMI协议的基础上。那么RMI就需要一个位置定位服务,即rmiregistry 。rmiregistry 是一个类似于CORBA命令服务或者LDAP的东西。rmiregistry可以是一个单独的进程,带上端口号执行JDK/bin/rmiregistry即可。也可以是嵌入在当前的java进程中。而com.sun.management.jmxremote.port这个参数就是指,rmiregistry这个服务在哪个端口监听。

然后,JMX Server会向这个rmiregistry注册自己。注册的时候需要提供一个主机地址和一个端口号。而这个端口号,默认是随机生成的。这个主机地址,常常很悲剧的是127.0.0.1或localhost。由于端口号是随机生的,这让系统管理员很为难。而且,如果那个主机地址是localhost……

其实几年前在做mz项目的时候就遇到这个问题了,只不过今天又遇到了,拿出来分享下。

MBeanServer的初始化代码得改成这样:

    final int port1=14000; //the port number on which the RMIServer and RMIConnection remote objects are exported
    final int port2=15000; //the port number of the RMI Registry
    LocateRegistry.createRegistry(port2);
    JMXServiceURL url = new JMXServiceURL(“service:jmx:rmi://0.0.0.0:” + 
              port1  + “/jndi/rmi://:” + port2 + “/jmxrmi”);
    java.util.HashMap<String,Object> env = new java.util.HashMap<String,Object>();
    JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(url, env, mBeanServer);        
    cs.start();
    //不要忘记调cs.stop();

用上面的代码,明确的指定端口号,就没有问题了。

Client代码如下:

             HashMap env = new HashMap(); 
             String[] credentials = new String[] { “controlRole” , “1234” }; 
             env.put(“jmx.remote.credentials”, credentials); 
             final String hostName=”192.168.1.145”;             
             final int port1=14000; 
            final int port2=15000; 
            JMXServiceURL url = new JMXServiceURL(“service:jmx:rmi://”+hostName+”:” + 
                      port1  + “/jndi/rmi://localhost:” + port2 + “/jmxrmi”);       
                                    
             JMXConnector jmxc = JMXConnectorFactory.connect(url, env); 
             MBeanServerConnection mbsc = jmxc.getMBeanServerConnection(); 
             String domains[] = mbsc.getDomains(); 
             for (int i = 0; i < domains.length; i++) { 
                System.out.println(“Domain[” + i + “] = ” + domains[i]); 
             } 
              
             jmxc.close();

用jconsole去连的时候,输入的端口号是上面的port2,也就是rmiregistry的端口。

另外,IP是127.0.0.1的原因是:它往RMI注册的时候需要获取本机IP,那么最传统的方式就是先用gethostname得到主机名,然后把主机名解析成IP。而很多Linux机器安装的时候没有正确的设置主机名,而是默认采用了localhost。用hostname改完主机名之后,不要忘记用 ping `hostname`测试下能不能ping通

原创粉丝点击