java rmi如何支持虚拟机(环境上仅有小网ip,而配置了大网ip的路由)

使用rmi进行分布式开发,服务器注册一个rmi服务,而客户端通过访问rmi服务来完成相关业务。

而现在遇到的问题是,rmi服务运行在虚拟机上(虚拟机上有小网的ip 192.168.X.X,配置路由IP 10.62.X.X),客户端仅能通过路由IP连接服务器而不能通过小网IP连接服务器,这样该如何注册RMI服务?

如下所示:

用xshell连接到10.62.X.X的机器,运行ifconfig只能看到192.168.X.X的IP地址:

[c:\~]$ 
Connecting to 10.62.44.138:22...
Connection established.
To escape to local shell, press 'Ctrl+Alt+]'.

Last login: Mon Mar  6 06:38:48 2017 from 10.62.100.97
[root@host-192-168-200-40 ~]# ifconfig
eth0      Link encap:Ethernet  HWaddr FA:16:3E:AC:69:74  
          inet addr:192.168.200.40  Bcast:192.168.200.255  Mask:255.255.255.0
          inet6 addr: fe80::f816:3eff:feac:6974/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:994873 errors:0 dropped:0 overruns:0 frame:0
          TX packets:615654 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:131935665 (125.8 MiB)  TX bytes:117107558 (111.6 MiB)


lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:8024568 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8024568 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:622160146 (593.3 MiB)  TX bytes:622160146 (593.3 MiB)


[root@host-192-168-200-40 ~]# 

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



参考了博客,大致了解了rmi的原理。

http://www.blogjava.net/freeman1984/archive/2014/12/05/421085.html

解决方案如下:

1. 统一使用小网ip或者回环IP127.0.0.1进行rmi服务注册

2. 编写一个类实现RMIClientSocketFactory指定使用路由IP创建socket连接

3. 客户端通过路由IP进行rmi远程方法调用


1.  统一使用小网ip或者回环IP127.0.0.1进行rmi服务注册

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import java.io.File;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;

public class RmiServiceServer {
    private static Logger dMsg = Logger.getLogger(RmiServiceServer.class);
    private static Registry registry = null;
    public static boolean startService(String connServerIP){
        boolean isSucc = false;
        try {
            int port = 9000;
            dMsg.info("start register agent service ...");
            System.setProperty("java.rmi.server.hostname", connServerIP);
	    RemoteServiceImpl service = new RemoteServiceImpl();
            String serverName = String.format("rmi://%s:%d/%s","127.0.0.1",port,"service");
            try{
                registry = LocateRegistry.createRegistry(port,new MyRMIClientSocketFactory(connServerIP,port), null);
                Naming.rebind(serverName, service);
                dMsg.info("succeed to register rmi service");
                isSucc = true;
            }catch (RemoteException e) {
                dMsg.error("fail to register rmi service " + e.getMessage(),e);
            }
       } catch (MalformedURLException e) {
            dMsg.error("fail to register rmi service " + e.getMessage(),e);
       } catch (RemoteException e) {
            dMsg.error("fail to register rmi service " + e.getMessage(),e);
       }
        return isSucc;
    }
    
    public static void stopService(){
        dMsg.info("start to dispose service...");
        try {
            Registry registry = LocateRegistry.getRegistry(9000);
            if(registry != null){
                registry.unbind("service");
                UnicastRemoteObject.unexportObject(registry, true);
            }
        } catch (RemoteException e1) {
            dMsg.error("RemoteException error:");
            dMsg.debug(e1.toString());
        } catch (NotBoundException e) {
            dMsg.error("service is ubinded.");
            dMsg.debug(e.toString());
        }
        dMsg.info("finish to dispose service...");
    }
    public static void main(String[] args)  {
        initLog4J();
        if(!startService(args[0])){
             System.exit(0);
        }
    }
    private static void initLog4J(){
        String confPath = System.getProperty("user.dir") + File.separator + "conf";
        String logConfigName = confPath + File.separator + "log4j.properties";
        PropertyConfigurator.configure(logConfigName);
    }
}

2. 编写一个类实现RMIClientSocketFactory执行使用路由IP创建socket连接

import java.io.IOException;
import java.io.Serializable;
import java.net.Socket;
import java.rmi.server.RMIClientSocketFactory;
public class MyRMIClientSocketFactory implements RMIClientSocketFactory,Serializable {
    private static final long serialVersionUID = 8782346882801831839L;
    private String host;
    private int port;

    public MyRMIClientSocketFactory(String host, int port) {
        this.host = host;
        this.port = port;
    }

    @Override
    public Socket createSocket(String host, int port) throws IOException {
        return new Socket(host,port);
    }
}

3. 客户端通过路由IP进行rmi远程方法调用

import org.apache.log4j.Logger;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.Remote;
import java.rmi.RemoteException;
public class RmiServiceClient {
    private static Logger dMsg = Logger.getLogger(RmiServiceClient.class);
    public static boolean connectService(String host,String port,String serviceName){
        boolean isConnected = false;
        String url = "rmi://"+host+":"+port+"/"+serviceName;
        dMsg.info("service url is:"+url);
        try {
            Remote remote = Naming.lookup(url);
            if(remote instanceof RemoteService){
                dMsg.debug("start call service...");
                RemoteService service = (RemoteService) remote;
                dMsg.debug("test print:" + service.print());
            }
            dMsg.debug("call service finished.");
            isConnected = true;
        } catch (MalformedURLException e) {
            dMsg.error("cannot parse url:");
            dMsg.debug(e.toString());
        } catch (RemoteException e) {
            dMsg.error("connect error:");
            dMsg.debug(e.toString());
        } catch (NotBoundException e) {
            dMsg.error("cannot found service:");
            dMsg.debug(e.toString());
        }
        return isConnected;
    }
    
    public static void inputTips(){
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        boolean flag = true;
        while(flag){
            try {
                dMsg.debug("Please input hostip:");
                String host = br.readLine();
                dMsg.debug("Please input service port:");
                String port = br.readLine();
                dMsg.debug("Please input service name:");
                String serviceName = br.readLine();
                if(connectService(host, port, serviceName)){
                    flag = false;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] args) {
        initLog4J();
        inputTips();
    }
    private static void initLog4J(){
        String confPath = System.getProperty("user.dir") + File.separator + "conf";
        String logConfigName = confPath + File.separator + "log4j.properties";
        PropertyConfigurator.configure(logConfigName);
    }
}








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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值