Java RMI

1、前言

RMI是远程方法调用(Remote Method Invocation)的简称,其是一种计算机之间利用远程对象互相调用实现双方通讯的一种通讯机制,它能够让一个Java虚拟机上的对象调用另一个Java虚拟机上对象的方法。Java RMI在JDK1.1中实现的,其它可以被看作是RPC的Java版本。但是传统RPC并不能很好地应用于分布式对象系统。而Java RMI 则支持存储于不同地址空间的程序级对象之间彼此进行通信,实现远程对象之间的无缝远程调用。

RMI相对于其它比较复杂的RPC要简单的多(比如Thrift、Grpc、Protoff等),本文仅仅简单阐述了其组成、实现原理图、代码示例。如果想深入学习和了解,可以自行解读源码或参照其它解读文档。


2、组成和原理

a、组成

一个正常工作的RMI系统大致由下面几个部分组成:

  • 远程服务接口的定义
  • 远程服务接口的具体实现
  • 桩(Stub)和框架(Skeleton)文件
  • 一个运行远程服务的服务器
  • 一个RMI命名服务,它允许客户端去发现这个远程服务
  • 类文件的提供者(一个HTTP或者FTP服务器)
  • 一个需要这个远程服务的客户端程序

b、原理

这里写图片描述


c、局限性

相比于其它RPC(Thrift、Grpc等),RMI存在许多的缺点:

  • RMI只能实现JAVA系统之间的调用,而WebService可以实现跨语言实现系统之间的调用。

  • RMI使用了JAVA默认的序列化方式,对于性能要求比较高的系统,可能需要其他的序列化方案来解决。

  • RMI服务在运行时难免会存在故障,例如,如果RMI服务无法连接了,就会导致客户端无法响应的现象。

  • RMI服务是基于远程接口提供的服务,一旦远程接口名称或者参数发生变化,客户端程序必须作出相应改变才能保证系统的稳定。


3、代码示例

远程接口类

package rmi;

import java.rmi.Remote;
import java.rmi.RemoteException;
/**
 * 
 * @author liqqc
 *
 */
public interface UserService extends Remote {

   public User getUserByid(long id) throws RemoteException;
}

远程接口实现类

package rmi;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
/**
 * 
 * @author liqqc
 *
 */
public class UserServiceImpl extends UnicastRemoteObject implements UserService{

    protected UserServiceImpl() throws RemoteException {
        super();
    }

    @Override
    public User getUserByid(long id) {
        User user = new User();
        user.setAge(10);
        user.setName("jack");
        user.setDesc("good man");
        user.setId(id);
        return user;
    }
}

服务器实现类

package rmi;

import java.net.MalformedURLException;
import java.rmi.AlreadyBoundException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
/**
 * 
 * @author liqqc
 *
 */
public class Server {

    public static void main(String[] args) {
        try {
            UserService userService = new UserServiceImpl();
            LocateRegistry.createRegistry(8080);
            Naming.bind("rmi://localhost:8080/user", userService);
            System.err.println("binding success");
        } catch (RemoteException e) {
            System.out.println("创建远程对象发生异常!");
            e.printStackTrace();
        } catch (AlreadyBoundException e) {
            System.out.println("发生重复绑定对象异常!");
            e.printStackTrace();
        } catch (MalformedURLException e) {
            System.out.println("URL异常!");
            e.printStackTrace();
        }
    }
}

客户端实现类

package rmi;

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

/**
 * 
 * @author liqqc
 *
 */
public class Client {
    public static void main(String[] args) {
        try { 
            UserService userService = (UserService) Naming.lookup("rmi://localhost:8080/user"); 
            System.out.println(userService.getUserByid(1000l)); 
        } catch (NotBoundException e) { 
            e.printStackTrace(); 
        } catch (MalformedURLException e) { 
            e.printStackTrace(); 
        } catch (RemoteException e) { 
            e.printStackTrace();   
        } 
    } 
}

实体类

package rmi;

import java.io.Serializable;
/**
 * 
 * @author liqqc
 *
 */
public class User implements Serializable{

    private String name;

    private String desc;

    private int age;

    private long id;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    @Override
    public String toString() {
        return "User [name=" + name + ", desc=" + desc + ", age=" + age + ", id=" + id + "]";
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值