Java RMI实现RPC(远程过程调用)

发布时间 2023-08-26 15:03:17作者: Nemuzuki

RMI(Remote Method Invocation,远程方法调用)是一个Java RPC的API,用于一台主机传递参数并远程调用另一台主机上的方法,下面给出一个简单实例。

环境:win10宿主机作为rmi client,ubuntu虚拟机(IP为192.168.129.49)作为rmi server。现在client希望向server传递参数,调用server端的服务并获取返回值

  • 在server上均创建HelloService.java(远程服务接口), HelloServiceImpl.java(远程服务接口的具体实现), RMIServer.java(服务端代码)
  • 在client上只需创建HelloService.java(远程服务接口), RMIClient.java(客户端代码)
  • 注意:服务端和客户端的package(我这里是com.ydj.rmi)必须相同,否则报错!

HelloService.java定义了一个远程服务HelloService,包含一个接口welcome()

package com.ydj.rmi;

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface HelloService extends Remote {
    public String welcome(String name) throws RemoteException;
}

HelloServiceImpl.java具体实现了welcome(),输出Hello+传来的字符串参数

package com.ydj.rmi;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class HelloServiceImpl extends UnicastRemoteObject implements HelloService {
    @Override
    public String welcome(String name) throws RemoteException {
        return "Hello " + name;
    }
    public HelloServiceImpl() throws RemoteException{
    }
}

server端代码:在本地URL 192.168.129.49:1099/Hello 上启动服务。

package com.ydj.rmi;
import java.net.MalformedURLException;
import java.rmi.AlreadyBoundException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class RMIServer {
    public static void main(String[] args) throws RemoteException, MalformedURLException, AlreadyBoundException {
        HelloService helloService = new HelloServiceImpl();
        LocateRegistry.createRegistry(1099);
        Naming.bind("rmi://192.168.129.49:1099/Hello",helloService);
        System.out.println("service start");
    }
}

client端代码:请求虚拟机上的服务,并传参字符串mika。如果需要传递一个对象,则需要序列化

package com.ydj.rmi;

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;

public class RMIClient {
    public static void main(String[] args) throws RemoteException, NotBoundException, MalformedURLException {
        HelloService helloService = (HelloService) Naming.lookup("rmi://192.168.129.49:1099/Hello");
        System.out.println(helloService.welcome("mika"));
    }
}

先启动server,然后运行client,client调用了server的welcome()成功输出:

Hello mika

注意:如果报错java.rmi.ConnectException: Connection refused to host: 127.0.1.1,表明server端的/etc/hosts文件需要修改,将原来的127.0.1.1 主机名改为192.168.129.49 主机名即可。