1.RPC
RPC(Remote Procedure Call Protocol)远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC不依赖于具体的网络传输协议,tcp、udp等都可以。由于存在各式各样的变换和细节差异,相应的rpc也派生出了各式远程过程通信协议。RPC是跨语言的通信标准,SUN和微软都有其实现,比如RMI可以被看作SUN对RPC的Java版本( 实现),而微软的DCOM就是建立在ORPC协议之上。一言以蔽之,RPC是协议,而无论是SUN的RMI还是微软的DCOM都是对该协议的不同实现,二者都为编程人员提供了应用PRC技术的程序接口(API)。
个人总结:RPC协议的实现框架比如RMI等 应该 是通过Socket接口里来使用TCP/IP协议来实现网络通信的。其他常用应用层协议包括FTP、HTTP、TELNET、SMTP等也是通过Socket这个门面接口来使用TCP/IP协议来实现网络通信的。
Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式(Facade),它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。
有关Socket的更多内容,详见:http://blog.csdn.net/zolalad/article/details/45599199
2. J2EE项目-使用JDK自带的RPC实现——RMI
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,运行环境)的平台上。但由于JRMP是专为Java对象制定的,因此,RMI对于用非Java语言开发的应用系统的支持不足。不能与用非Java语言书写的对象进行通信。
3. Hadoop中自定义的RPC实现原理
Hadoop作为一个存储与服务的基础性平台,同时它的内部有采用了master/slave架构,那么其内部通信和与客户端的交互就是必不可少的了。Hadoop在实现时抛弃了JDK自带的一个RPC实现——RMI,而自己基于IPC模型实现了一个更高效的轻量级RPC。
SOCKET使用时可以指定协议TCP,UDP等;
RIM使用JRMP协议,JRMP又是基于TCP/IP;
RPC底层使用SOCKET接口,定义了一套远程调用方法;
HTTP是建立在TCP上,不是使用SOCKET接口,需要连接方主动发数据给服务器,服务器无法主动发数据个客户端;
可以用socket实现HTTP;
其实符合HTTP规范的就是HTTP协议,不管用什么技术。
转自:http://blog.csdn.net/a19881029/article/details/9465663
RMI:远程方法调用(Remote Method Invocation)。能够让在某个Java虚拟机上的对象像调用本地对象一样调用另一个java 虚拟机中的对象上的方法。
RMI远程调用步骤:
1,客户对象调用客户端辅助对象上的方法
2,客户端辅助对象打包调用信息(变量,方法名),通过网络发送给服务端辅助对象
3,服务端辅助对象将客户端辅助对象发送来的信息解包,找出真正被调用的方法以及该方法所在对象
4,调用真正服务对象上的真正方法,并将结果返回给服务端辅助对象
5,服务端辅助对象将结果打包,发送给客户端辅助对象
6,客户端辅助对象将返回值解包,返回给客户对象
7,客户对象获得返回值
对于客户对象来说,步骤2-6是完全透明的
Java RMI的缺点:
1,从代码中也可以看到,代码依赖于ip与端口
2,RMI依赖于Java远程消息交换协议JRMP(java Remote Messaging Protocol),该协议为java定制,要求服务端与客户端都为java编写
转自:http://www.cnblogs.com/dongguacai/p/5617698.html
RMI的定义
RPC (Remote Procedure Call):远程方法调用,用于一个进程调用另一个进程中的过程,从而提供了过程的分布能力。
RMI(Remote Method Invocation):远程方法调用,即在RPC的基础上有向前迈进了一步,提供分布式对象间的通讯。允许运行在一个java 虚拟机的对象调用运行在另一个java虚拟机上对象的方法。这两个虚拟机可以是运行在相同计算机上的不同进程中,也可以是运行在网络上的不同计算机中。
RMI的全称宗旨就是尽量简化远程接口对象的调用。
RMI大大增强了java开发分布式应用的能力,例如可以将计算方法复杂的程序放在其他的服务器上,主服务器只需要去调用,而真正的运算是在其他服务器上进行,最后将运算结果返回给主服务器,这样就减轻了主服务器的负担,提高了效率(但是也有其他的开销)。
RMI网络模型
在设计初始阶段,我们真正想要的是这样一种机制,客户端程序员以常规方式进行方法调用,而无需操心将数据发送到网络上或者解析响应之类的问题。所以才有了如下的网络模型:在客户端为远程对象安装一个代理。代理是位于客户端虚拟机中的一个对象,它对于客户端程序来说,就像是要访问的远程对象一样。客户端调用此代理时,只需进行常规的方法调用。而客户端代理则负责使用网络协议与服务器进行联系。
现在的问题在于代理之间是如何进行通信的?通常有三种方法:
1、CORBA:通过对象请求代理架构,支持任何编程语言编写的对象之间的方法调用。
2、SOAP
3、RMI:JAVA的远程方法调用技术,支持java的分布式对象之间的方法调用。
其中CORBA与SOAP都是完全独立于言语的,可以使用C、C++、JAVA来编写,而RMI只适用于JAVA。
转自:http://blog.csdn.net/liuxuezong/article/details/6256549
RMI与Socket
一般来说,基于CS(client-server)软件架构的开发技术有很多种。比较常用的有:基于 socket的网络编程、RPC、基于Java技术的RMI(当然C#也有类似技术)、CORBA等。在这里我们只是对基于socket的网络编程与 RMI作个对比,有助于我们了解它们各自的应用领域,帮助我们在面对一个具体问题的时候选用适合的技术。另外,本文所做的讨论可以认为是脱离了语言层面的 东西,只是对技术的本身做一个讨论,无关乎你是用C++、C#或Java 在开发。
一、RMI技术简介
本文就以Java为例,简单介绍一下RMI技术。
从Java1.1开始,远程方法调用作为Java分布式对象技术成为Java核心的API之一(在java.rmi.* 包)。RMI的引入,使得Java程序之间能够实现灵活的,可扩展的分布式通信。RMI允许Java对象存在于多个不同的地址空间,分布在不同的Java 虚拟机上。每一个地址空间可以在同一台主机上或者网络上不同的计算机上。由于远程方法调用跨越不同的虚拟机边界到不同的指定的地址空间,所以没有对象共享 的全局变量,这就需要对象序列化(Object Serialization)API,它使得Java对象能够在不同的JVM之间传递。对象序列化是特别为Java的对象设计的,这就意味着Java程序 中的对象可以作为对象参数存取(可序列化的对象必须实现Serializable接口)。结合RMI和对象序列化机制,就可以访问越过本地Java虚拟机 边界的对象以及数据。通过RMI,可以调用远程对象的远程方法,而通过Java对象序列化机制可以将对象传递给这些方法。
最基本的Java模型并没有提供将远程主机上的Java对象看作本地Java程序地址空间一部分的能力,而RMI祢补了这一不足。另外,由于Java与硬件平台无关的特性,无论是同构的系统还是异构的系统,RMI不需移植就可以顺利运行。
RMI为Java平台的分布式计算提供了一个简单而直接的模型。因为Java的RMI技术是基于Java平台的,所以它将Java平台的安全性和可移植性 等优点带到了分布式计算中。RMI大大扩展Java的网络计算能力,它为编写基于分布式对象技术的企业级Internet/Intranet应用提供了强 大的系统平台支持。
Java RMI 体系结构如下图:
二、基于socket的网络编程
当你使用socket进行网络应用开发的时候,一般的思路是“消息驱动逻辑”,即这样的软件系统一般具有以下特点:
(1) 客户端与服务器端依靠消息进行通讯。
(2) 客户端或者服务器端都需要一个消息派遣器,将消息投递给具体的massage handler
(3) 客户端或者服务器端利用massage handler进行逻辑事务处理
见下图:
使用socket开发的软件系统,从技术的本质上来讲,有以下几个特点:
(1) 基于TCP协议的通讯
(2) 应用程序本身需要提供对消息的序列化处理(所谓的序列化指的是将消息输出到网络流中)
(3) 客户端与服务器端需要事先商议好它们之间的通讯协议即它们交互的消息格式
(4) 由于是消息驱动逻辑,从本质上决定了这样的编程模式很难面向对象化
三、RMI Vs Sochet
RMI技术比较socket的网络编程主要有以下几个方面:
第一、.RMI是面向对象的,而后者不是。
第二、.RMI是与语言相绑定的。比如当你使用Java RMI技术的时候,客户端与服务器端都必须使用Java开发。而socket的网络编程是使用独立于开发语言的,甚至独立于平台。基于socket的网络 编程,客户端与服务器端可以使用不同开发语言和不同的平台。
第三、从网络协议栈的观点来看,RMI与socket的网络编程处于不同层次上。基于socket的网络编程位于TCP协议之上,而RMI在TCP协议之 上,又定义了自己的应用协议,其传输层采用的是Java远程方法协议(JRMP)。可见,在网络协议栈上,基于RMI的应用位置更高一些,这也决定了,与 socket的网络编程相比,RMI会丧失一些灵活性和可控性,但是好处是它带给了应用开发者更多的简洁,方便和易用。比如:如果你用的是RMI,你不需 要关心消息是怎么序列化的,你只需要像本地方法调用一样,使用RMI。代价是:应用开发者无法很好地控制消息的序列化机制。
第四、这是最后一点不同,我认为也是比较重要的一点,就是两种方法的性能比较,其往往决定着你将使用那种技术来开发你的应用。以下引用Adrian Reber在Network-programming with RMI文中对TCP和RMI所做的一个比较,其做的实验主要是对两者在网络传输的带宽上作的对比: 在网络上传输2 byte的有效数据,对于TCP而言,总共有478 byte被额外传输,而对于RMI, 1645byte被额外传输。
以下是两者的trace结果:
TCP:
46037 > 12345 [SYN] Seq=801611567 Ack=0 Win=5840 Len=0
12345 > 46037 [SYN, ACK] Seq=266515894 Ack=801611568 Win=10136 Len=0
46037 > 12345 [ACK] Seq=801611568 Ack=266515895 Win=5840 Len=0
12345 > 46037 [PSH, ACK] Seq=266515895 Ack=801611568 Win=10136 Len=1
46037 > 12345 [ACK] Seq=801611568 Ack=266515896 Win=5840 Len=0
12345 > 46037 [FIN, PSH, ACK] Seq=266515896 Ack=801611568 Win=10136 Len=1
46037 > 12345 [RST, ACK] Seq=801611568 Ack=266515898 Win=5840 Len=0
RMI:
42749 > rmiregistry [SYN, ECN, CWR]
Seq=3740552479 Ack=0 Win=32767 Len=0
rmiregistry > 42749 [SYN, ACK, ECN]
Seq=3749262223 Ack=3740552480 Win=32767 Len=0
42749 > rmiregistry [ACK] Seq=3740552480 Ack=3749262224 Win=32767 Len=0
JRMI, Version: 2, StreamProtocol
rmiregistry > 42749 [ACK] Seq=3749262224 Ack=3740552487 Win=32767 Len=0
JRMI, ProtocolAck
42749 > rmiregistry [ACK] Seq=3740552487 Ack=3749262240 Win=32767 Len=0
Continuation
rmiregistry > 42749 [ACK] Seq=3749262240 Ack=3740552506 Win=32767 Len=0
JRMI, Call
rmiregistry > 42749 [ACK] Seq=3749262240 Ack=3740552556 Win=32767 Len=0
JRMI, ReturnData
42749 > rmiregistry [ACK] Seq=3740552556 Ack=3749262442 Win=32767 Len=0
JRMI, Ping
JRMI, PingAck
42749 > rmiregistry [ACK] Seq=3740552557 Ack=3749262443 Win=32767 Len=0
JRMI, DgcAck
42749 > rmiregistry [FIN, ACK]
Seq=3740552572 Ack=3749262443 Win=32767 Len=0
rmiregistry > 42749 [FIN, ACK]
Seq=3749262443 Ack=3740552573 Win=32767 Len=0
42749 > rmiregistry [ACK] Seq=3740552573 Ack=3749262444 Win=32767 Len=0
实验的结果是:RMI与TCP based socket相比,传输相同的有效数据,RMI需要占用更多的网络带宽(protocol overhead)。从这里,我们可以得出一个一般性的结论:RMI主要是用于远程方法的”调用“(RMI是多么的名符其实:)),其技术内涵强调的是 “调用”,基于此,我能想到的是:移动计算,和远程控制,当你的应用不需要在client与server之间传输大量的数据时,RMI是较好的选择,它简 洁、易于开发。但是,一旦你的应用需要在client与server之间传输大量的数据,极端的,比如FTP应用,则RMI是不适合的,我们应该使用 socket。