Java APi 之 RMI远程方法调用

一、什么是RPC

RPC全称是remote procedure call,即远程过程调用。它是一种协议,用于从远程计算机上请求服务。

例如有两台服务器A和B,A上的应用想要调用B上应用的方法,但是他们在不同的服务器,所以不能通过内存调用的方式,所以我们理所当然地去考虑通过网络来实现函数调用。RPC也就是能够实现A上的应用能够直接调用B上应用的方法的协议。

注:RPC和HTTP的不同点主要是在于针对使用场景而形成的不同特性,RPC协议主要应用于服务器的内部,也针对服务而形成如错误重试、服务发现等特性。

 

二、什么是RMI

RMI全称remote method invocation,即远程方法调用,是Java对RPC的一种客户端/服务端的实现,基于一个注册表Registry,如图

服务端创建并发布远程对象,注册表处理远程对象的映射地址;客户端通过映射地址从注册表获取远程对象,调用相应的方法

 

三、RMI使用步骤

1、定义远程对象接口

2、实现远程对象

3、实现服务端

4、实现客户端

 

四、代码示例

定义远程对象接口Hello

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

/**
 * 远程对象接口定义
 *
 * @author lay
 * @date 2018/8/29 13:23
 */
public interface Hello extends Remote {

    /**
     * sayHello方法定义
     *
     * @return
     * @throws RemoteException
     */
    String sayHello() throws RemoteException;
}

实现服务端,这里包括实现远程对象,发布和注册映射

import java.rmi.AlreadyBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;

/**
 * RMI服务端
 *
 * @author lay
 * @date 2018/8/29 13:24
 */
public class Server implements Hello {

    /**
     * 实现远程接口方法
     *
     * @return 字符串
     * @throws RemoteException
     */
    @Override
    public String sayHello() throws RemoteException {
        return "hello RMI";
    }

    public static void main(String[] args) throws RemoteException, AlreadyBoundException {
        // 获取远程接口的远程对象
        Server server = new Server();
        // 发布远程对象到RMI
        Hello hello = (Hello) UnicastRemoteObject.exportObject(server, 8080);
        // 获取注册表
        Registry registry = LocateRegistry.createRegistry(8080);
        // 绑定映射地址
        registry.bind("hello", hello);
        System.out.printf("服务端启动成功");
    }
}

客户端实现

import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

/**
 * RMI客户端
 *
 * @author lay
 * @date 2018/8/29 13:33
 */
public class Client {

    public static void main(String[] args) throws RemoteException, NotBoundException {
        // 获取注册表
        Registry registry = LocateRegistry.getRegistry(8080);
        // 查找远程对象
        Hello hello = (Hello) registry.lookup("hello");
        // 调用方法
        String content = hello.sayHello();
        System.out.printf("content:" + content);
    }
}

启动服务端,客户端调用的输出结果为:

content:hello RMI

 

参考文章:

https://docs.oracle.com/javase/7/docs/technotes/guides/rmi/hello/hello-world.html#register

posted @ 2018-08-29 14:55  __lay  阅读(1349)  评论(0编辑  收藏  举报