简介:

RPC是远程过程调用(Remote Procedure Call)的缩写形式。SAP系统RPC调用的原理其实很简单,有一些类似于三层构架的C/S系统,第三方的客户程序通过接口调用SAP内部的标准或自定义函数,获得函数返回的数据进行处理后显示或打印。RPC采用客户机/服务器模式。请求程序就是一个客户机,而服务提供程序就是一个服务器。首先,客户机调用进程发送一个有进程参数的调用信息到服务进程,然后等待应答信息。在服务器端,进程保持睡眠状态直到调用信息到达为止。当一个调用信息到达,服务器获得进程参数,计算结果,发送答复信息,然后等待下一个调用信息,最后,客户端调用进程接收答复信息,获得进程结果,然后调用执行继续进行。

远程调用流程图:

工作原理:

运行时,一次客户机对服务器的RPC调用,其内部操作大致有如下十步:

1.调用客户端句柄;执行传送参数

2.调用本地系统内核发送网络消息

3.消息传送到远程主机

4.服务器句柄得到消息并取得参数

5.执行远程过程

6.执行的过程将结果返回服务器句柄

7.服务器句柄返回结果,调用远程系统内核

8.消息传回本地主机

9.客户句柄由内核接收消息

10.客户接收句柄返回的数据

远程调用的几种方式:

在java领域中知名的有:RMI、XML-RPC、Binary-RPC、SOAP、CORBA、JMS等。

1.RMI

     RMI是个典型的为java定制的远程通信协议, 我们都知道,在single vm中,我们能够通过直接调用java object instance来实现通信,那么在远程通信时,假设也能依照这样的方式当然是最好了。这样的远程通信的机制成为RPC(RemoteProcedure Call),RMI正是朝着这个目标而诞生的。传输的标准格式是Java Object Stream;基于Java串行化机制将请求的Java Object信息转化为流。传输协议是Socket。

2.XML-RPC

XML-RPC也是一种和RMI类似的远程调用的协议,它和RMI的不同之处在于它以标准的xml格式来定义请求的信息(请求的对象、方法、參数 等),这种优点是在跨语言通讯的时候也能够使用。所以RMI与RPC的差别之中的一个是RPC是跨语言的。 传输的标准格式是XML。将XML转化为流。传输协议是HTTP。

3.Binary-RPC

Binary-RPC和XML-RPC是差点儿相同,不同之处仅在于传输的标准格式由XML转为了二进制的格式。 传输的标准格式是二进制文件。将二进制文件转化为传输的流。传输协议是HTTP。

4.SOAP

SOAP(SimpleObject Access Protocol),是一个用于分布式环境的、轻量级的、基于XML进行信息交换的通信协议,能够觉得SOAP是XML RPC的高级版。两者的原理全然同样。都是http+XML,不同的仅在于两者定义的XML规范不同。SOAP也是Webservice採用的服务调用协议标准。

5.CORBA

Common Object Request BrokerArchitecture(公用对象请求代理[调度]程序体系结构),是一组用来定义“分布式对象系统”的标准,由OMG(Object Menagement Group)作为发起和标准制定单位。CORBA的目的是定义一套协议,符合这个协议的对象能够互相交互,不论它们是用什么样的语言写的。不论它们执行于 什么样的机器和操作系统。CORBA是个类似于SOA的体系架构。涵盖可选的远程通信协议,但其本身不能列入通信协议。

6.JMS

JMS是实现java领域远程通信的一种手段和方法。基于JMS实现远程通信时和RPC是不同的。尽管能够做到RPC的效果,但由于不是从协议 级别定义的。因此我们不觉得JMS是个RPC协议,但它确实是个远程通信协议,在其它的语言体系中也存在着类似JMS的东西,能够统一的将这类机制称为消 息机制。而消息机制呢,一般是高并发、分布式领域推荐的一种通信机制,这里的主要一个问题是容错。JMS注重的是消息交换,RMI注重的是对象方法调用,所以目的不同。JMS大多时候是异步的松耦合,RMI大多时候是同步的紧耦合。JMS规定的传输格式是Message,将參数信息放入Message中,传输协议不限。基于JMS也是经常使用的实现远程异步调用的方法之中的一个。

RMI介绍

  远程方法调用(RMI)顾名思义是一台机器上的程序调用另一台机器上的方法。这样可以大致知道RMI是用来干什么的,但是这种理解还不太确切。RMI是Java支撑分布式系统的基石,例如著名的EJB组件。RMI是远程过程调用(RPC)的一种面向对象实现,RMI底层是通过socket通信和对象序列化技术来实现的。这里引用Wikipedia对RMI的介绍:

RMI基本原理

  RMI的目的就是要使运行在不同的计算机中的对象之间的调用表现得像本地调用一样。RMI 应用程序通常包括两个独立的程序:服务器程序和客户机程序。RMI 需要将行为的定义与行为的实现分别定义, 并允许将行为定义代码与行为实现代码存放并运行在不同的 JVM 上。在 RMI 中, 远程服务的定义是存放在继承了 Remote 的接口中。远程服务的实现代码存放在实现该定义接口的类中。RMI 支持两个类实现一个相同的远程服务接口: 一个类实现行为并运行在服务器上, 而另一个类作为一个远程服务的代理运行在客户机上。客户程序发出关于代理对象的调用方法, RMI 将该调用请求发送到远程 JVM 上, 并且进一步发送到实现的方法中。实现方法将结果发送给代理, 再通过代理将结果返回给调用者。

RMI 构建三个抽象层, 高层覆盖低层, 分别负责Socket通信, 参数和结果的序列化和反序列化等工作。存根( Stub) 和骨架( Skeleton) 合在一起形成了 RMI 构架协议。下面的引用层被用来寻找各自的通信伙伴, 在这一层还有一个提供名字服务的部分, 称为注册表( registry) 。最下一层是传输层, 是依赖于 TCP/IP 协议实现客户机与服务器的互联。

当客户端调用远程对象方法时, 存根负责把要调用的远程对象方法的方法名及其参数编组打包,并将该包向下经远程引用层、传输层转发给远程对象所在的服务器。通过 RMI 系统的 RMI 注册表实现的简单服务器名字服务, 可定位远程对象所在的服务器。该包到达服务器后, 向上经远程引用层, 被远程对象的 Skeleton 接收, 此 Skeleton 解析客户包中的方法名及编组的参数后, 在服务器端执行客户要调用的远程对象方法, 然后将该方法的返回值( 或产生的异常) 打包后通过相反路线返回给客户端, 客户端的 Stub 将返回结果解析后传递给客户程序。事实上, 不仅客户端程序可以通过存根调用服务器端的远程对象的方法, 而服务器端的程序亦可通过由客户端传递的远程接口回调客户端的远程对象方法。在分布式系统中, 所有的计算机可以是服务器, 同时又可以是客户机。

RMI应用示例

Remote 接口用于标识其方法可以从非本地虚拟机上调用的接口。任何远程对象都必须直接或间接实现此接口。只有在“远程接口”(扩展 java.rmi.Remote 的接口)中指定的这些方法才可远程使用。 也就是说需要远程调用的方法必须在扩展Remote接口的接口中声名并且要抛出RemoteException异常才能被远程调用。远程对象必须实现java.rmi.server.UniCastRemoteObject类,这样才能保证客户端访问获得远程对象时,该远程对象将会把自身的一个拷贝序列化后以Socket的形式传输给客户端,此时客户端所获得的这个拷贝称为“存根”,而服务器端本身已存在的远程对象则称之为“骨架”。其实此时的存根是客户端的一个代理,用于与服务器端的通信,而骨架也可认为是服务器端的一个代理,用于接收客户端的请求之后调用远程方法来响应客户端的请求。 远程对象的接口和实现必须在客户端和服务器端同时存在并且保持一致才行。

代码实现:

HelloDefine.java

 package com.etc;

 import  java.rmi.Remote;
import java.rmi.RemoteException;
//远程接口定义
public interface HelloDefine extends Remote {
public String helloWorld() throws RemoteException;
public String sayHello(String name) throws RemoteException;
}

HelloDefineImp.java

 package com.etc;

 import  java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
//远程接口实现
public class HelloDefineImp extends UnicastRemoteObject implements HelloDefine {
private static final long serialVersionUID = 1L;
public HelloDefineImp() throws RemoteException {
super();
}
public String helloWorld() throws RemoteException {
return "Hello AlphaGo!";
}
public String sayHello(String name) throws RemoteException {
return "Hello" + name +"!";
}
}

HelloServer.java

 package com.etc;

 import  java.net.MalformedURLException;
import java.rmi.AlreadyBoundException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
//服务端绑定
public class HelloServer {
HelloDefine hello;
public void server() throws RemoteException, MalformedURLException, AlreadyBoundException {
hello = new HelloDefineImp();
//远程对象注册表实例
LocateRegistry.createRegistry(8888);
//把远程对象注册到RMI注册服务器上
Naming.bind("rmi://localhost:8888/Hello", hello);
System.out.println("server:对象绑定成功!");
}
}

HelloClient.java

 package com.etc;

 import  java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
//客户端调用
public class HelloClient {
public HelloDefine hello;
public void client() throws MalformedURLException, RemoteException, NotBoundException {
//在RMI注册表中查找指定对象
hello = (HelloDefine) Naming.lookup("rmi://localhost:8888/Hello");
//调用远程对象方法
System.out.println("client:");
System.out.println(hello.helloWorld());
System.out.println(hello.sayHello("起飞吧骚年!"));
}
}

转载内容来源:https://www.cnblogs.com/wxisme/p/5296441.html

远程过程调用概述-RMI简介的更多相关文章

  1. Java RMI 简介及其优劣势总结

    今天,帮别人看UDAS配置问题时,看到采用的是RMI方式的调用,如:rmi://10.20.134.140:2299/DataServer,而且这个端口是被直接硬编码在UDAS的代码中的.既然看到了, ...

  2. SDN概述:简介、工具、环境部署

    一.前言: 本文初步接触 SDN 的相关概念.需要依次完成下面几项任务: SDN 简介 SDN 工具 SDN 环境部署 推荐阅读 推荐阅读下述内容: Ethane 项目,openflow 的基础 op ...

  3. IOS学习笔记02---语言发展概述,计算机语言简介.

    IOS学习笔记02---语言发展概述,计算机语言简介. ------------------------------------------------------------------------ ...

  4. 概述Log4j简介

    在强调可重用组件开发的今天,除了自己从头到尾开发一个可重用的日志操作类外,Apache为我们提供了一个强有力的日志操作包-Log4j. Log4j是Apache的一个开放源代码项目,通过使用Log4j ...

  5. redis_NoSql入门概述数据模型简介

    以下面的背景去对比关系型数据库和非关系型数据库的差异(一个电商客户.订单.订购.地址模型来对比以下关系型数据库和非关系型数据库) 传统数据库一般设计会使用ER图(1:1/1:N/N:N,主键等) 而N ...

  6. STP概述简介及生成树算法

    目录: STP概述 STP简介 生成树算法 选择根网桥 选择根端口 选择指定端口 BPDU(桥协议数据单元) STP利用BPDU选择根网桥 STP的收敛 VLAN与STP关系 MSTP多生成树协议华为 ...

  7. Java远程方法调用(Remote Method Invocation,RMI)

    Java RMI简介: 它是Java的一个核心API和类库,允许一个Java虚拟机上运行的Java程序调用不同虚拟机上运行的对象中的方法,即使这两个虚拟机运行于物理隔离的不同主机上. Java RMI ...

  8. 【Hibernate】Hibernate系列1之概述

    概述 Hibernate简介 1.2.安装hibernate tools插件 1.3.HelloWorld示例 1.3.1.加入jar包 1.3.2.开发步骤 hibernate generator ...

  9. 1.5分布式通讯框架-RMI

    分布式通信框架-RMI讲解 什么是RPC Remote procedure call protocal RPC协议其实是一个规范.常用PRC框架:Dubbo.Thrif.RMI.Webservice. ...

随机推荐

  1. python 字典详细使用

    1. 字典 字典是无序.可变序列. 定义字典时,每个元素的键和值用冒号分隔,元素之间用逗号分隔,所有的元素放在一对大括号“{}”中. 字典中的键可以为任意不可变数据,比如整数.实数.复数.字符串.元组 ...

  2. 1分钟快速制作漂亮的H5本地记事本

    大家好,以前给大家分享过一个五步骤制作精美的HTML5时钟的文章,点击回顾<五步教你制作漂亮精致的HTML时钟>,还有<一分钟教你如何实现唯美的文字描边>:今天给大家分享一个用 ...

  3. Android 基本控件相关知识整理

    Android应用开发的一项重要内容就是界面开发.对于用户来说,不管APP包含的逻辑多么复杂,功能多么强大,如果没有提供友好的图形交互界面,将很难吸引最终用户.作为一个程序员如何才能开发出友好的图形界 ...

  4. Kali学习笔记29:默认安装漏洞

    文章的格式也许不是很好看,也没有什么合理的顺序 完全是想到什么写一些什么,但各个方面都涵盖到了 能耐下心看的朋友欢迎一起学习,大牛和杠精们请绕道 默认安装漏洞: 早期Windows默认自动开启很多服务 ...

  5. 【MML】华为MML AAA接口联调,Java版本

    1.我们先设置一些常量数据 package cn.cutter.ztesoft.HuWeiMML.constrant; /** * @description: AAA接口常量设置 * @author: ...

  6. ES6常用特性总览

    以前看过一遍es6,今天面试时被问到了一个很简单的es6特性,竟然没回答上来,特来重温一下es6,做个总结性笔记. 一.什么是es6 es6是新版本JavaScript语言的标准,在2015年6月发布 ...

  7. Python Selenium 常用方法总结(不断补充)

    还有此篇内容也丰富Selenium常见元素定位方法和操作的学习介绍 selenium Python 总结一些工作中可能会经常使用到的API. 1.获取当前页面的Url 方法:current_url 实 ...

  8. JAVA UUID 生成唯一标识

    Writer:BYSocket(泥沙砖瓦浆木匠) 微博:BYSocket 豆瓣:BYSocket Reprint it anywhere u want 需求 项目在设计表的时候,要处理并发多的一些数据 ...

  9. Apache-Flink深度解析-TableAPI

    您可能感兴趣的文章合集: Flink入门 Flink DataSet&DataSteam API Flink集群部署 Flink重启策略 Flink分布式缓存 Flink重启策略 Flink中 ...

  10. 非业务 Oracle SQL 语句备份

    1.创建一个将 Oracle 生成的 GUID 格式化为标准的 GUID 的函数 2.在 PLSQL 中测试并输出语句异常的语句块 3.在查询语句中日期的一种特殊表示方法 4.利用 ROWNUM 做分 ...