让JAVA的RMI彻底穿透防火墙

我自己最早听到RMI还是在EJB里面,至于之前为什么会去看EJB还是有历史原因的,后来Spring里面经常使用,在Spring里面调用还是很方便的,配置一下就可以了,没有Spring的框架下就是纯java的RMI了。 
      近来几天困扰的一个RMI问题,终于解决了,解决之前是纠结的,解决之后是收获的,正是因为如此,才有深入了解JAVA的RMI原理。出现这个问题根本原因就是防火墙。
       RMI的原理,用图来说明

让JAVA的RMI彻底穿透防火墙 - ytsm04 - ytsm04的博客

 

 这个过程并不复杂,但是上图只是个大概,最为重要的还是RMI与客户端通信,必须有两个端口,其一为固定的端口默认为1099,其二为随机生成的数据端口

      在没有防火墙限制的情况下,可能都不会有什么问题,按正常流程调用即可。往往我们的生产环境,是开通防火墙的,只开通个别已知的端口,对未知的端口是不允许访问的,那么就会导致RMI通信失败。错误信息如下:

java.rmi.ConnectIOException: error during JRMP connection establishment; nested
exception is:
        java.net.SocketTimeoutException: Read timed out
        at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:286
)

 这个错误信息就足以确定是某个端口没有开通的问题,通常对问题的的定位花时间更多,尤其是下环境比较复杂的情况下,反而解决方法是相对简单的,只须把随机生成的数据端口改为固定端口,不随机,并且在防火墙中开放此端口。

解决方法:

1.写一个SMRMISocket.java类


/**
 * <p>
 *   设置RMI固定端口,避免在启用防火墙时,客户端无法调用
 * </p>
 * @author huangshuidan
 * @date 2011-12-09
 *
 */
public class SMRMISocket extends RMISocketFactory{
 private static int SOCKET_PORT=5902;//固定RMI的数据库端口
 
 /* (non-Javadoc)
  * @see java.rmi.server.RMISocketFactory#createServerSocket(int)
  */
 public ServerSocket createServerSocket(int port) throws IOException {
  if (port == 0){
         port = SOCKET_PORT;//不指定就随机
         System.out.println("固定RMI的数据库端口:"+port);
  }
     return new ServerSocket(port);  
 }

 /* (non-Javadoc)
  * @see java.rmi.server.RMISocketFactory#createSocket(java.lang.String, int)
  */
 public Socket createSocket(String host, int port) throws IOException {
  return new Socket(host,port);  
 }
 
}

 可以把SOCKET_PORT这个固定端口写到配置文件去。

2.//固定RMI数据端口--begin
   RMISocketFactory.setSocketFactory(new SMRMISocket());
   //固定RMI数据端口--end
   LocateRegistry.createRegistry(1099);

   IHello hello = new HelloImpl();

注意这三行的顺序设置固定端口,一定要放在实例化UnicastRemoteObject对象之前,不然还是随机生成数据端口。

=======================================================================================

      到这里为止就足以解决问题了,可是我们项目的环境相当复杂,更新后不生效,后面一一排查,发现有个配置跟RMI服务冲突了,

修改了下就全部搞定。

     一分辛苦一分收获,假设没有这个问题的出现,我也不会深入去研究RMI,最多就停留在会用,所以会用和深入学习还是有相当大的差距。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黄豆2019

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值