热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

关于rmi——各种资料的摘抄

 背景Distributedsystemsrequirethatcomputationsrunningindifferentaddressspaces,potentiallyond

 

背景

Distributed systems require that computations running in different address spaces, potentially on different hosts, be able to communicate. For a basic communication mechanism, the JavaTM programming language supports sockets, which are flexible and sufficient for general communication. However, sockets require the client and server to engage in applications-level protocols to encode and decode messages for exchange, and the design of such protocols is cumbersome and can be error-prone.

An alternative to sockets is Remote Procedure Call (RPC), which abstracts the communication interface to the level of a procedure call. Instead of working directly with sockets, the programmer has the illusion of calling a local procedure, when in fact the arguments of the call are packaged up and shipped off to the remote target of the call. RPC systems encode arguments and return values using an external data representation, such as XDR.

RPC, however, does not translate well into distributed object systems, where communication between program-level objects residing in different address spaces is needed. In order to match the semantics of object invocation, distributed object systems require remote method invocation or RMI. In such systems, a local surrogate (stub) object manages the invocation on a remote object.

 谷歌翻译:分布式系统要求在不同地址空间(可能在不同主机上)运行的计算能够进行通信。对于基本通信机制,JavaTM编程语言支持套接字,这些套接字灵活且足以进行一般通信。然而,套接字要求客户端和服务器参与应用程序级协议以对消息进行编码和解码以进行交换,并且这种协议的设计是麻烦的并且可能容易出错。

套接字的替代方法是远程过程调用(RPC),它将通信接口抽象到过程调用的级别。程序员不是直接使用套接字,而是具有调用本地过程的错觉,实际上调用的参数被打包并运送到远程调用目标。 RPC系统使用外部数据表示(例如XDR)对参数和返回值进行编码。

但是,RPC不能很好地转换为分布式对象系统,其中需要驻留在不同地址空间中的程序级对象之间的通信。为了匹配对象调用的语义,分布式对象系统需要远程方法调用或RMI。在此类系统中,本地代理(存根)对象管理远程对象上的调用。

 

Java RMI,即 远程方法调使用(Remote Method Invocation),

It is a mechanism that allows an object residing in one system (JVM) to access/invoke an object running on another JVM.

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

一种使用于实现远程过程调使用(RPC)(Remote procedure call)的Java API, 可以直接传输序列化后的Java对象和分布式垃圾收集。它的实现依赖于Java虚拟机(JVM),因而它仅支持从一个JVM到另一个JVM的调使用。

 

in an RMI application, we write two programs, a server program (resides on the server) and a client program (resides on the client).



  • Inside the server program, a remote object is created and reference of that object is made available for the client (using the registry).



  • The client program requests the remote objects on the server and tries to invoke its methods.



框架:



  • Transport Layer − This layer connects the client and the server. It manages the existing connection and also sets up new connections.



  • Stub − A stub is a representation (proxy) of the remote object at client. It resides in the client system; it acts as a gateway for the client program.



  • Skeleton − This is the object which resides on the server side. stub communicates with this skeleton to pass request to the remote object.



  • RRL(Remote Reference Layer) − It is the layer which manages the references made by the client to the remote object.




  • Working of an RMI Application

    The following points summarize how an RMI application works −



    • When the client makes a call to the remote object, it is received by the stub which eventually passes this request to the RRL.



    • When the client-side RRL receives the request, it invokes a method called invoke() of the object remoteRef. It passes the request to the RRL on the server side.



    • The RRL on the server side passes the request to the Skeleton (proxy on the server) which finally invokes the required object on the server.



    • The result is passed all the way back to the client.





举例

 

 


1、接口定义

远程对象的能力是由在客户端和服务器之间共享的接口所表示的:

 


package rmi;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface Warehouse extends Remote
{
double getPrice(String description) throws RemoteException;
}

 

远程对象的接口必须扩展Remote接口,它位于java.rmi包中。接口中所有的方法必须声明抛出RemoteException异常。这是因为远程方法总是存在失败的可能,所以java编程语言要求每一次远程方法的调用都必须捕获RemoteException,并且指明当调用不成功时应执行的相应处理操作。


2、接口的实现


package rmi;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.HashMap;
import java.util.Map;
public class WarehouseImpl extends UnicastRemoteObject implements Warehouse
{
private static final long serialVersiOnUID= 1L;
private Map prices;
protected WarehouseImpl() throws RemoteException
{
prices = new HashMap();
prices.put("mate7",3700.00);

}
public double getPrice(String description) throws RemoteException
{
Double price = prices.get(description);
return price == null? 0 : price;
}
}

你可以看出这个类是远程方法调用的目标,因为它扩展自UnicastRemoteObject,这个类的构造器使得它的对象可供远程访问。


3、RMI注册表:通过JNDI发布RMI服务

1、要访问服务器上的一个远程对象时,客户端必须先得到一个本地的存根对象,也就是客户端机器上的代理对象。那么问题来了,如何才能得到这个存根呢?

2、为此,JDK提供了自举注册服务(bootstrap registry service),服务器程序应该使用自举注册服务来注册至少一个远程对象。

3、而要注册一个远程对象,需要一个RMI URL和一个对实现对象的引用。

4、RMI 的URL以rmi:开头,后接域名或IP地址(host),紧接着是端口号(port),最后是服务名(service)。

     如:rmi://regserver.mycompany.cmo:99/central_warehouse

     如果我们是在本地发布RMI服务,那么host就是“localhost”,此外RMI默认的端口号是“1099”,当然我们也可以自行设置,只要不与其他端口重复即可。              service实际上是基于同一个host与port下唯一的服务名。

发布RMI服务:


1 package rmi;
2
3 import java.net.MalformedURLException;
4 import java.rmi.AlreadyBoundException;
5 import java.rmi.Naming;
6 import java.rmi.RemoteException;
7 import java.rmi.registry.LocateRegistry;
8
9 import javax.naming.NamingException;
10
11
12 public class WarehouseServer
13 {
14 public static void main(String[] args) throws RemoteException, NamingException, MalformedURLException, AlreadyBoundException
15 {
16
17 WarehouseImpl centralWarehouse = new WarehouseImpl();
18
19 //创建注册表
20 LocateRegistry.createRegistry(1099);
//bind方法绑定了RMI地址与RMI服务实现类。发布服务
21 Naming.bind("rmi://localhost:1099/central_warehoues",centralWarehouse);
22
23
24 }
25 }

 


 4、调用RMI服务


1 package rmi;
2
3 import java.net.MalformedURLException;
4 import java.rmi.Naming;
5 import java.rmi.NotBoundException;
6 import java.rmi.RemoteException;
7 import javax.naming.NamingException;
8
9 public class WarehouseClient
10 {
11 public static void main(String[] args) throws NamingException, RemoteException, MalformedURLException, NotBoundException
12 {
13
14 String url = "rmi://localhost:1099/central_warehoues";
15 Warehouse centralWarehouse = (Warehouse) Naming.lookup(url);//centralWarehouse相当于stub
16 String descr = "mate7";
17 double price = centralWarehouse.getPrice(descr);
18 System.out.println(descr + ":" + price);
19 }
20 }



  1. 借助JNDI这个所谓的命名与目录服务,我们成功地发布并调用了RMI服务。实际上,JNDI就是一个注册表,服务端将服务对象放入到注册表中,客户端从注册表中获取服务对象。


  1. 2、在服务端我们发布了RMI服务,并在JNDI中进行了注册,此时就在服务端创建了一个Skeleton(骨架),当客户端第一次成功连接JNDI并获取远程服务对象后,立马在本地创建了一个Stub(存根)。



  1. 3、远程通信实际是通过Skeleton与Stub来完成的,数据是基于TCP/IP协议,在“传输层”上发送的。



  1. 4、毋庸置疑,理论上RMI一定比WebService要快,毕竟WebService是基于http协议的,而http所携带的数据是通过“应用层”来传输的。传输层较应用层更为底层,越底层越快。

 

 

 


RMI的局限性

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

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

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

资料来源:
Java Remote Method Invocation Specification
分布式架构基础:Java RMI详解-新闻热点
对JAVA RMI的认识 - 冬瓜蔡 - 博客园
https://www.tutorialspoint.com/java_rmi/java_rmi_introduction.htm

 

 


推荐阅读
  • spring boot使用jetty无法启动 ... [详细]
  • 本文基于Java官方文档进行了适当修改,旨在介绍如何实现一个能够同时处理多个客户端请求的服务端程序。在前文中,我们探讨了单客户端访问的服务端实现,而本篇将深入讲解多客户端环境下的服务端设计与实现。 ... [详细]
  • publicclassBindActionextendsActionSupport{privateStringproString;privateStringcitString; ... [详细]
  • 本文探讨了如何通过Service Locator模式来简化和优化在B/S架构中的服务命名访问,特别是对于需要频繁访问的服务,如JNDI和XMLNS。该模式通过缓存机制减少了重复查找的成本,并提供了对多种服务的统一访问接口。 ... [详细]
  • Python 伦理黑客技术:深入探讨后门攻击(第三部分)
    在《Python 伦理黑客技术:深入探讨后门攻击(第三部分)》中,作者详细分析了后门攻击中的Socket问题。由于TCP协议基于流,难以确定消息批次的结束点,这给后门攻击的实现带来了挑战。为了解决这一问题,文章提出了一系列有效的技术方案,包括使用特定的分隔符和长度前缀,以确保数据包的准确传输和解析。这些方法不仅提高了攻击的隐蔽性和可靠性,还为安全研究人员提供了宝贵的参考。 ... [详细]
  • MongoDB高可用架构:深入解析Replica Set机制
    MongoDB的高可用架构主要依赖于其Replica Set机制。Replica Set通过多个mongod节点的协同工作,实现了数据的冗余存储和故障自动切换,确保了系统的高可用性和数据的一致性。本文将深入解析Replica Set的工作原理及其在实际应用中的配置和优化方法,帮助读者更好地理解和实施MongoDB的高可用架构。 ... [详细]
  • 1、编写一个Java程序在屏幕上输出“你好!”。programmenameHelloworld.javapublicclassHelloworld{publicst ... [详细]
  • Asynchronous JavaScript and XML (AJAX) 的流行很大程度上得益于 Google 在其产品如 Google Suggest 和 Google Maps 中的应用。本文将深入探讨 AJAX 在 .NET 环境下的工作原理及其实现方法。 ... [详细]
  • Zabbix自定义监控与邮件告警配置实践
    本文详细介绍了如何在Zabbix中添加自定义监控项目,配置邮件告警功能,并解决测试告警时遇到的邮件不发送问题。 ... [详细]
  • 处理Android EditText中数字输入与parseInt方法
    本文探讨了如何在Android应用中从EditText组件安全地获取并解析用户输入的数字,特别是用于设置端口号的情况。通过示例代码和异常处理策略,展示了有效的方法来避免因非法输入导致的应用崩溃。 ... [详细]
  • Maven + Spring + MyBatis + MySQL 环境搭建与实例解析
    本文详细介绍如何使用MySQL数据库进行环境搭建,包括创建数据库表并插入示例数据。随后,逐步指导如何配置Maven项目,整合Spring框架与MyBatis,实现高效的数据访问。 ... [详细]
  • 长期从事ABAP开发工作的专业人士,在面对行业新趋势时,往往需要重新审视自己的发展方向。本文探讨了几位资深专家对ABAP未来走向的看法,以及开发者应如何调整技能以适应新的技术环境。 ... [详细]
  • 一、Advice执行顺序二、Advice在同一个Aspect中三、Advice在不同的Aspect中一、Advice执行顺序如果多个Advice和同一个JointPoint连接& ... [详细]
  • 本文详细介绍了JQuery Mobile框架中特有的事件和方法,帮助开发者更好地理解和应用这些特性,提升移动Web开发的效率。 ... [详细]
  • Web动态服务器Python基本实现
    Web动态服务器Python基本实现 ... [详细]
author-avatar
allenn2012
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有