jmx rmi 穿越防火墙问题及jmxmp的替代方案

前段时间遇到jmx使用rmi协议进行连接穿越防火墙的问题,查了很久终于查到了原因。

      

1.     对rmi的工作方式进行了了解,发现jmx如果采用rmi作为传输协议的话,客户端需要进行两个连接,如:JMXConnectorServer的JMXServiceURL为如下形式:service:jmx:rmi://localhost:5000/jndi/rmi://localhost:6000/jmxrmi

则首先客户端连接到rmiregistry上得到真实服务器的stub(如rmi://localhost:6000/rmxrmi),然后客户端再根据该stub连接到真实的服务器上(如rmi://localhost:5000)。如果jmx服务端省略了蓝色部分的标注,默认的通信端口是随机产生的。针对目前现网的情况,如果现网只开放了一个注册端口,如果要通过防火墙进行通信还需要开放一个通信端口,另外jmx服务端也需要固定通信端口。

   通过在防火墙上开放两个端口一般能够解决穿越防火墙的问题,但针对防火墙做了内外网IP映射情况,还需要增加额外的配置,使服务端带回的stub为外网IP而非内网IP ,System.setProperty("java.rmi.server.hostname","外网IP");比解决方案没有验证,具体可参见http://blog.csdn.net/ktyl2000/article/details/4485896


2  为避开rmi穿越防火墙问题,通常采用jmx消息协议(jmxmp)来代替rmi,使用jmxmp协议较为简单,并且服务端不需要进行端口注册过程,使用jmxmp的相关代码如下:

服务端:

public class TestJmxmpServer {
  public static void main(String[] args)throws IOException{
 MBeanServer platform = ManagementFactory.getPlatformMBeanServer();
     String serviceURL="service:jmx:jmxmp://localhost:9877/ogsi";
    JMXConnectorServer connectServer = JMXConnectorServerFactory.newJMXConnectorServer(new JMXServiceURL(serviceURL), null, platform);
     connectServer.start();
     System.out.println("server start success");
 }
 
  }

客户端:

public class TestClient {
  public static void main(String[] args){
 try {
JMXConnector jmxConnector = JMXConnectorFactory.connect(new JMXServiceURL("service:jmx:jmxmp://localhost:9877/osgi"));
MBeanServerConnection mbsc = jmxConnector.getMBeanServerConnection();
if(mbsc!=null){
System.out.println("success");
}
 } catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
  }
}

为了支持jmxmp协议,客户端和服务端均需要增加jmxremote_optionnal.jar


3  由于我运行的程序均在OSGI环境下作为独立bundle进行启动,开发为bundle的过程中,由于类加载问题,通常要么提示不支持jmxmp,要么找不到一些其他类。

    针对这两个问题:

 客户端的修改:

       要支持jmxmp协议,需要在客户端连接之前设置环境map,如:

       Map<String, Object> env = new HashMap<String, Object>(); 
       env.put(JMXConnectorServerFactory.PROTOCOL_PROVIDER_PACKAGES,   "com.sun.jmx.remote.protocol.jmxmp"); 否则可能加载不到jmxmp相关的connector

      另外jmx类加载过程中按照双亲委派机制,加载不到javax开头的包中的类,因此在客服端环境map中还需要设置默认类加载器

      env.put(JMXConnectorServerFactory.DEFAULT_CLASS_LOADER,JMXConnectorServerFactory.class.getClassLoader());

   客户端连接的代码第二个参数改成环境map,如JMXConnectorFactory.connect(new JMXServiceURL(jmxUrl),env);

   并且客户端实际需要三个jar包 jmxremote_optional.jar 、jmxremote.jar、jmxri.jar

服务端的修改:

      服务端代码不需要修改,除了jmxremote_optional.jar外,还需要增加jmxremote.jar这个包。


根据此可以在OSGI环境下成功支持jmxmp协议的连接。

  




 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值