前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >分布式计算第四章 RMI

分布式计算第四章 RMI

作者头像
张哥编程
发布于 2024-12-19 03:25:56
发布于 2024-12-19 03:25:56
15600
代码可运行
举报
文章被收录于专栏:云计算linux云计算linux
运行总次数:0
代码可运行

分布式计算第四章 RMI

1.定义

RPC (Remote Procedure Call):远程方法调用,用于一个进程调用另一个进程中的过程,从而提供了过程的分布能力。

RMI(Remote Method Invocation):远程方法调用,即在RPC的基础上有向前迈进了一步,提供分布式对象间的通讯。允许运行在一个java 虚拟机的对象调用运行在另一个java虚拟机上对象的方法。这两个虚拟机可以是运行在相同计算机上的不同进程中,也可以是运行在网络上的不同计算机中。

RMI的全称宗旨就是尽量简化远程接口对象的调用。

RMI大大增强了java开发分布式应用的能力,例如可以将计算方法复杂的程序放在其他的服务器上,主服务器只需要去调用,而真正的运算是在其他服务器上进行,最后将运算结果返回给主服务器,这样就减轻了主服务器的负担,提高了效率(但是也有其他的开销)。

2.为什么需要RMI

为了解决日益庞大的计算模型,网络模型

2.1设计原理

在设计初始阶段,我们真正想要的是这样一种机制,客户端程序员以常规方式进行方法调用,而无需操心将数据发送到网络上或者解析响应之类的问题。所以才有了如下的网络模型:​在客户端为远程对象安装一个代理。代理是位于客户端虚拟机中的一个对象,它对于客户端程序来说,就像是要访问的远程对象一样​。客户端调用此代理时,只需进行常规的方法调用。而客户端代理则负责使用网络协议与服务器进行联系。

2.2 网络模型

分布式计算第四章 RMI_分布式实践
分布式计算第四章 RMI_分布式实践

计算模型

分布式计算第四章 RMI_分布式课程_02
分布式计算第四章 RMI_分布式课程_02

体系结构

分布式计算第四章 RMI_分布式计算_03
分布式计算第四章 RMI_分布式计算_03

底层类

分布式计算第四章 RMI_分布式课程_04
分布式计算第四章 RMI_分布式课程_04

2.3工作原理

RMI能让一个Java程序去调用网络中另一台计算机的Java对象的方法,那么调用的效果就像是在本机上调用一样。通俗的讲:A机器上面有一个class,通过远程调用,B机器调用这个class 中的方法。

RMI,远程方法调用(Remote Method Invocation)是Enterprise JavaBeans的支柱,是建立分布式Java应用程序的方便途径。RMI是非常容易使用的,但是它非常的强大。

RMI的基础是接口,RMI构架基于一个重要的原理:定义接口和定义接口的具体实现是分开的。下面我们通过具体的例子,建立一个简单的远程计算服务和使用它的客户程序

1、存根:当客户端要调用远程对象的一个方法时,实际上调用的是代理对象上的一个普通方法,​我们称此代理对象为存根(stub)。​存根位于客户端机器上,而非服务器上。

2、参数编组:存根会将​远程方法所需的参数打包成一组字节​,对参数编码的过程就称为参数编组。参数编组的目的是将参数转换成适合在虚拟机之间进行传递的格式,在RMI协议中,对象是使用序列化机制进行编码的。

2.4 RMI用途

RMI的用途是为分布式Java应用程序之间的远程通信提供服务,提供分布式服务。

目前主要应用时封装在各个J2EE项目框架中,例如Spring,EJB(Spring和EJB均封装了RMI技术)

在Spring中实现RMI:

①在服务器端定义服务的接口,定义特定的类实现这些接口;

②在服务器端使用org.springframework.remoting.rmi.RmiServiceExporter类来注册服务;

③在客户端使用org.springframework.remoting.rmi.RmiProxyFactoryBean来实现远程服务的代理功能;

④在客户端定义访问与服务器端服务接口相同的类

2.5 局限性

RMI目前使用Java远程消息交换协议JRMP(Java Remote Messaging Protocol)进行通信。JRMP是专为Java的远程对象制定的协议,由于JRMP是专为Java对象制定的,因此,RMI对于用非Java语言开发的应用系统的支持不足。不能与用非Java语言书写的对象进行通信(意思是只支持客户端和服务器端都是Java程序的代码的远程调用)。

3.代码步骤

3.1远程接口

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package cn.com.tt.rmiserver.stub;

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

import cn.com.tt.rmiserver.bean.Account;

public interface UserManagerInterface extends Remote{
    public String getUserName() throws RemoteException;
    public Account getAdminAccount() throws RemoteException;
}

3.2接口实现类

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package cn.com.tt.rmiserver;

import java.rmi.RemoteException;

import cn.com.tt.rmiserver.stub.UserManagerInterface;
import cn.com.tt.rmiserver.bean.Account;

public class UserManagerImp implements UserManagerInterface {
    public UserManagerImp() throws RemoteException {

    }
    private static final long serialVersionUID = -3111492742628447261L;

    public String getUserName() throws RemoteException{
        return "TT";
    }
    public Account getAdminAccount() throws RemoteException{
        Account account=new Account();
        account.setUsername("TT");
        account.setPassword("123456");
        return account;
    }
}

3.3 实体类

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package cn.com.tt.rmiserver.bean;

import java.io.Serializable;

public class Account implements Serializable,Cloneable{
    private static final long serialVersionUID = -1858518369668584532L;
    private String username;
    private String password;

    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
}

3.3服务器类

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package cn.com.tt.rmiserver.entry;

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

import cn.com.tt.rmiserver.UserManagerImp;
import cn.com.tt.rmiserver.stub.UserManagerInterface;

public class Entry {
    public static void main(String []args) throws AlreadyBoundException, RemoteException{
        UserManagerImp userManager=new UserManagerImp();
        UserManagerInterface userManagerI=(UserManagerInterface)UnicastRemoteObject.exportObject(userManager,0);
        // Bind the remote object's stub in the registry
        Registry registry = LocateRegistry.createRegistry(2002);

        registry.rebind("userManager", userManagerI);
        System.out.println("server is ready");
        }
}

3.4客户端类。

  1. 新建一个java Project,编写客户端代码。
  2. 把Server端的Account类和接口UserManagerInterface,引用到新建的项目中。
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package weiblog.rmi;

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

import cn.com.tt.rmiserver.stub.UserManagerInterface;

public class ClientEntry {

    public static void main(String []args){

        try {
            Registry registry = LocateRegistry.getRegistry("localhost",2002);
            UserManagerInterface userManager = (UserManagerInterface)registry.lookup("userManager");
            System.out.println("用户名是"+userManager.getAdminAccount().getUsername()
                    +"密码"+userManager.getAdminAccount().getPassword());
        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NotBoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-03-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 分布式计算第四章 RMI
    • 1.定义
    • 2.为什么需要RMI
    • 3.代码步骤
    • 3.3 实体类
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档