参考链接: Java中的远程方法调用RMI

一、RMI 远程方法调用

RMI(Remote Method Invocation)远程方法调用。能够让在客户端Java虚拟机上的对象像调用本地对象一样调用服务端java 虚拟机中的对象上的方法。使用代表:EJB  RMI远方法程调用步骤:

1、客户调用客户端辅助对象stub上的方法2、客户端辅助对象stub打包调用信息(变量、方法名),通过网络发送给服务端辅助对象skeleton3、服务端辅助对象skeleton将客户端辅助对象发送来的信息解包,找出真正被调用的方法以及该方法所在对象4、调用真正服务对象上的真正方法,并将结果返回给服务端辅助对象skeleton5、服务端辅助对象将结果打包,发送给客户端辅助对象stub6、客户端辅助对象将返回值解包,返回给调用者7、客户获得返回值

参考:https://blog.csdn.net/guyuealian/article/details/51992182

二、RPC 远程过程调用

RPC(Remote Procedure Call Protocol)远程过程调用协议,通过网络从远程计算机上请求调用某种服务。它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。 使用代表:Dubbo一次RPC调用的过程大概有10步:

1、执行客户端调用语句,传送参数2、调用本地系统发送网络消息3、消息传送到远程主机4、服务器得到消息并取得参数 5、根据调用请求以及参数执行远程过程(服务)6、执行过程完毕,将结果返回服务器句柄7、服务器句柄返回结果,调用远程主机的系统网络服务发送结果8、消息传回本地主机 9、客户端句柄由本地主机的网络服务接收消息10、客户端接收到调用语句返回的结果数据

远程过程调用带来的新问题 在远程调用时,我们需要执行的函数体是在远程的机器上的,也就是说,Multiply是在另一个进程中执行的。这就带来了几个新问题:

Call ID映射。我们怎么告诉远程机器我们要调用Multiply,而不是Add或者FooBar呢?在本地调用中,函数体是直接通过函数指针来指定的,我们调用Multiply,编译器就自动帮我们调用它相应的函数指针。但是在远程调用中,函数指针是不行的,因为两个进程的地址空间是完全不一样的。所以,在RPC中,所有的函数都必须有自己的一个ID。这个ID在所有进程中都是唯一确定的。客户端在做远程过程调用时,必须附上这个ID。然后我们还需要在客户端和服务端分别维护一个 {函数 <–> Call ID} 的对应表。两者的表不一定需要完全相同,但相同的函数对应的Call ID必须相同。当客户端需要进行远程调用时,它就查一下这个表,找出相应的Call ID,然后把它传给服务端,服务端也通过查表,来确定客户端需要调用的函数,然后执行相应函数的代码。 序列化和反序列化。客户端怎么把参数值传给远程的函数呢?在本地调用中,我们只需要把参数压到栈里,然后让函数自己去栈里读就行。但是在远程过程调用时,客户端跟服务端是不同的进程,不能通过内存来传递参数。甚至有时候客户端和服务端使用的都不是同一种语言(比如服务端用C++,客户端用Java或者Python)。这时候就需要客户端把参数先转成一个字节流,传给服务端后,再把字节流转成自己能读取的格式。这个过程叫序列化和反序列化。同理,从服务端返回的值也需要序列化反序列化的过程。 网络传输。远程调用往往用在网络上,客户端和服务端是通过网络连接的。所有的数据都需要通过网络传输,因此就需要有一个网络传输层。网络传输层需要把Call ID和序列化后的参数字节流传给服务端,然后再把序列化后的调用结果传回客户端。只要能完成这两者的,都可以作为传输层使用。因此,它所使用的协议其实是不限的,能完成传输就行。尽管大部分RPC框架都使用TCP协议,但其实UDP也可以,而gRPC干脆就用了HTTP2。Java的Netty也属于这层的东西。 所以,要实现一个RPC框架,其实只需要把以上三点实现了就基本完成了。

Call ID映射可以直接使用函数字符串,也可以使用整数ID。映射表一般就是一个哈希表。 序列化反序列化可以自己写,也可以使用Protobuf或者FlatBuffers之类的。 网络传输库可以自己写socket,或者用asio,ZeroMQ,Netty之类。

参考:https://my.oschina.net/zjllovecode/blog/1790024

三、RMI与RPC的区别

1、方法调用方式不同:

RMI调用方法,RMI中是通过在客户端的Stub对象作为远程接口进行远程方法的调用。每个远程方法都具有方法签名。如果一个方法在服务器上执行,但是没有相匹配的签名被添加到这个远程接口(stub)上,那么这个新方法就不能被RMI客户方所调用。RPC调用函数,RPC中是通过网络服务协议向远程主机发送请求,请求包含了一个参数集和一个文本值,通常形成“classname.methodname(参数集)”的形式。这就向RPC服务器表明,被请求的方法在“classname”的类中,名叫“methodname”。然后RPC服务器就去搜索与之相匹配的类和方法,并把它作为那种方法参数类型的输入。这里的参数类型是与RPC请求中的类型是匹配的。一旦匹配成功,这个方法就被调用了,其结果被编码后通过网络协议发回。2、适用语言范围不同:

RMI只用于Java,支持传输对象。RPC是基于C语言的,不支持传输对象,是网络服务协议,与操作系统和语言无关。3、调用结果的返回形式不同:

RMI是面向对象的,Java是面向对象的,所以RMI的调用结果可以是对象类型或者基本数据类型。RPC的结果统一由外部数据表示(External Data Representation,XDR)语言表示,这种语言抽象了字节序类和数据类型结构之间的差异。只有由XDR定义的数据类型才能被传递,可以说RMI是面向对象方式的Java RPC。

四、附录

RPC(Remote Procedure Call Protocol)远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC不依赖于具体的网络传输协议,tcp、udp等都可以。由于存在各式各样的变换和细节差异,相应的RPC也派生出了各式远程过程通信协议。RPC是跨语言的通信标准,SUN和微软都有其实现,比如:RMI可以被看作SUN对RPC的Java版本(实现),而微软的DCOM就是建立在ORPC协议之上。一言以蔽之,RPC是协议,而无论是SUN的RMI还是微软的DCOM都是对该协议的不同实现,二者都为编程人员提供了应用PRC技术的程序接口(API)。

RMI是Java的一组拥护开发分布式应用程序的API。RMI使用Java语言接口定义了远程对象,它集合了Java序列化和Java远程方法协议(Java Remote Method Protocol)。简单地说,这样使原先的程序在同一操作系统的方法调用,变成了不同操作系统之间程序的方法调用,由于J2EE是分布式程序平台,它以RMI机制实现了程序组件在不同操作系统之间的通信。比如,一个EJB可以通过RMI调用Web上另一台机器上的EJB远程方法。RMI(Remote Method Invocation,远程方法调用)是用Java在JDK1.1中实现的,它大大增强了Java开发分布式应用的能力。

Java作为一种风靡一时的网络开发语言,其巨大的威力就体现在它强大的开发分布式网络应用的能力上,而RMI就是开发百分之百纯Java的网络分布式应用系统的核心解决方案之一。其实RMI可以被看作是RPC的Java版本(实现)。传统RPC并不能很好地应用于分布式对象系统,而Java RMI 则支持存储于不同地址空间的程序级对象之间彼此进行通信,实现远程对象之间的无缝远程调用。RMI目前使用Java远程消息交换协议(JRMP,Java Remote Messaging Protocol)进行通信。JRMP是专为Java的远程对象制定的协议。因此,Java RMI具有Java的“Write Once,Run Anywhere”的优点,是分布式应用系统的百分之百纯Java解决方案。用Java RMI开发的应用系统可以部署在任何支持JRE(Java Run Environment Java,Java运行环境)的平台上。但由于JRMP是专为Java对象制定的,因此,RMI对于用非Java语言开发的应用系统的支持不足。不能与用非Java语言书写的对象进行通信。

Hadoop作为一个存储与服务的基础性平台,同时它的内部有采用了master/slave架构,那么其内部通信和与客户端的交互就是必不可少的了。Hadoop在实现时抛弃了JDK自带的一个RPC实现–RMI,而自己基于IPC模型实现了一个更高效的轻量级RPC。

RMI的局限性之一:RMI对服务器的IP地址和端口依赖很紧密,但是在开发的时候不知道将来的服务器IP和端口如何,但是客户端程序依赖这个IP和端口。这个问题有两种解决途径:一是通过DNS来解决,二是通过封装将IP暴露到程序代码之外。注意:我们在实际开发中,我们是知道服务器IP和端口的。RMI的局限性之二:是RMI是Java语言的远程调用,两端的程序语言必须是Java实现,对于不同语言间的通讯可以考虑用WebService或者公用对象请求代理体系(CORBA)来实现。

JMS:Java 消息服务(Java Messaging Service) 是一种允许应用程序创建、发送、接受和读取消息的Java API。JMS 在其中扮演的角色与JDBC 很相似,正如 JDBC 提供了一套用于访问各种不同关系数据库的公共API,JMS 也提供了独立于特定厂商的企业消息系统访问方式。 使用JMS 的应用程序被称为JMS客户端,处理消息路由与传递的消息系统被称为 JMS Provider,而JMS 应用则是由多个JMS 客户端和一个 JMS Provider 构成的业务系统。发送消息的JMS 客户端被称为生产者(producer),而接收消息的JMS 客户端则被称为消费者(consumer)。同一JMS 客户端既可以是生产者也可以是消费者。JMS 的编程过程很简单,概括为:应用程序A 发送一条消息到消息服务器(也就是JMS Provider)的某个目的地(Destination),然后消息服务器把消息转发给应用程序B。因为应用程序A 和应用程序B 没有直接的代码关连,所以两者实现了解偶。

RMI和JMS的区别:1、传输方式上

JMS 与 RMI 的区别在于:采用 JMS 服务,对象是在物理上被异步从网络的某个 JVM 上直接移动到另一个 JVM 上。RMI 对象是绑定在本地 JVM 中,只有函数参数和返回值是通过网络传送的。2、方法调用上

RMI 一般都是同步的,也就是说,当client端调用Server端的一个方法的时候,需要等到对方的返回,才能继续执行client端,这个过程跟调用本地方法感觉上是一样的,这也是RMI的一个特点。JMS 一般只是一个点发出一个Message到Message Server端,发出之后一般不会关心谁用了这个message。一般RMI的应用是紧耦合,JMS的应用相对来说是松散耦合的应用。

[转载] 远程方法调用(RMI)与远程过程调用(RPC)相关推荐

  1. 转载-- http接口、api接口、RPC接口、RMI、webservice、Restful等概念

    http接口.api接口.RPC接口.RMI.webservice.Restful等概念 收藏 Linux一叶 https://my.oschina.net/heavenly/blog/499661 ...

  2. 转:传入的表格格式数据流(TDS)远程过程调用(RPC)协议流不正确 .

    近期在做淘宝客的项目,大家都知道,淘宝的商品详细描述字符长度很大,所以就导致了今天出现了一个问题 VS的报错是这样子的  " 传入的表格格式数据流(TDS)远程过程调用(RPC)协议流不正确 ...

  3. 修复远程过程调用 (RPC) 时发生的各种问题KB908521

    当系统出现RPC通讯问题时可以尝安装KB908521进行修复. 安装本更新程序可以解决当您在 Microsoft Windows Server 2003 和 Microsoft Windows XP ...

  4. hessian、rmi、dubbo与rpc关系

    hessian.rmi.dubbo与rpc之间的关系 单的说,RPC就是从一台机器(客户端)上通过参数传递的方式调用另一台机器(服务器)上的一个函数或方法(可以统称为服务)并得到返回的结果. RPC ...

  5. 传入的表格格式数据流(TDS)远程过程调用(RPC)协议流不正确。参数 1 (“@xx“): 对于类型特定的元数据,数据类型 0x62 (sql_variant)的类型无效。

    传入的表格格式数据流(TDS)远程过程调用(RPC)协议流不正确.参数 1 ("@xx"): 对于类型特定的元数据,数据类型 0x62 (sql_variant)的类型无效. 解决 ...

  6. 什么是RMI,什么是RPC,两者之间的区别是什么?

    这里是修真院后端小课堂,每篇分享文从 [背景介绍][知识剖析][常见问题][解决方案][编码实战][扩展思考][更多讨论][参考文献] 八个方面深度解析后端知识/技能,本篇分享的是: [什么是RMI, ...

  7. 传入的表格格式数据流(TDS)远程过程调用(RPC)协议流不正确

    记录一次很少见的Sql异常排查,异常内容:         传入的表格格式数据流(TDS)远程过程调用(RPC)协议流不正确.参数 5 ("@TestValue"): 提供的值不是 ...

  8. com.microsoft.sqlserver.jdbc.SQLServerException: 传入的表格格式数据流(TDS)远程过程调用(RPC)协议流不正确。此 RPC 请求中提供了过多的参数。

    sqlserver在做批量插入的时候出现这个错误: com.microsoft.sqlserver.jdbc.SQLServerException: 传入的表格格式数据流(TDS)远程过程调用(RPC ...

  9. RabbitMQ远程过程调用(RPC)

    RabbitMQ远程过程调用(RPC) 准备环境 使用Pika RabbitMQ客户端,客户端版本(1.0.0以上) 客户端接口示例 FibonacciRpcClient是一个简单的客户端类,它暴露了 ...

最新文章

  1. python获取数据库查询的元数据_Python数据库、MySQL存储引擎、使用分区表、更改表结构、获取数据库元数据...
  2. 【Android-功能】Android应用增量更新
  3. spring使用JUnit测试,@Autowired无法注入原因
  4. java Junit 为什么@Test注解里的方法必须是public void修饰的
  5. Python的map、filter、reduce函数
  6. leaflet加载离线地图教程以及下载离线地图瓦片工具
  7. 第一次参加数学建模竞赛如何夺取一等奖
  8. Quick BI电子表格: 新手亦可表格自由
  9. 中兴如何远程服务器时间同步,中兴通讯时间同步解决方案
  10. python爬虫判断cookie过期_当爬虫遇到cookie失效,怎样处理?
  11. mysql5.7.11无法启动_MySQL5.7.11免安装版的安装和配置:解决MYSQL 服务无法启动问题...
  12. 李梁北京大学 计算机,【资环学院】圆梦路上多楷模
  13. GitHub简单教程
  14. scrollbar wpf 高度_Wpf ScrollBar自定义样式
  15. 《信条》中国内地IMAX首周末票房表现强劲;洲际集团将在川滇环线新开四家酒店 | 美通企业日报...
  16. 数据结构与算法分析:C语言描述(原书第2版) PDF+源代码+习题答案
  17. Yaml:基本语法使用
  18. 十大编程语言的优劣对比简述
  19. 如何处理pagefile.sys占用太多C盘空间
  20. 如何快速提高Python能力

热门文章

  1. 【CSP】第20届CCF CSP计算机软件能力认证划水贴
  2. 【Luogu1341】无序字母对(并查集联通,欧拉路模板)
  3. java list平均分成5份_java中将一个List等分成n个list的工具方法(推荐)
  4. Python入门--字符串的分割操作,split,rsplit
  5. MYSQL MVCC 实现机制
  6. 字符串 kmp算法解析
  7. 算法时间复杂度分析专题一(帮助快速解题)
  8. opencv 图像平移、缩放、旋转、翻转 图像仿射变换
  9. [再学Python] - 4 - 循环
  10. Perceptual Losses for Real-Time Style Transfer and Super-Resolution 运行程序