深入剖析 Java RMI 技术实现原理

RMI(Remote Method Invocation)远程方法调用是 java 的核心技术之一。是 Enterprise JavaBeans 的基础技术,是 java 建立分布式应用程序的强大支柱。

RMI 允许一个应用程序访问另外一个服务器或虚拟机上的对象,方法和服务,它使远程方法调用就像在本地调用一样简单。它为用户屏蔽了底层的网络传输细节,使用的时候只需适当处理异常即可。所以 RMI 是非常容易使用的,但同时是非常强大的。

RMI 协议的数据序列化目前支持以下两种模式:
1.基于 JDK 本身的对象序列化
2.基于 HTTP 协议的数据序列化

协议数据序列化原文说明如下:


The RMI protocol makes use of two other protocols for its on-the-wire format: Java Object Serialization and HTTP. The Object Serialization protocol is used to marshal call and return data. The HTTP protocol is used to "POST" a remote method invocation and obtain return data when circumstances warrant. Each protocol is documented as a separate grammar. Nonterminal symbols in production rules may refer to rules governed by another protocol (either Object Serialization or HTTP). When a protocol boundary is crossed, subsequent productions use that embedded protocol.

[quote]
数据传输数据包一共分两种,一种是数据输出流,另一种是数据输入流。

输出流与输入流都是成对出现和使用。

输出流数据包格式


输出流数据包的内容说明如下:
◦Header 头
◦Messages 消息体
◦HttpMessage(可选)

Header:头数据包说明
0x4a 0x52 0x4d 0x49 Version Protocol

Header 包含四个固定字节的标识加版本号,协议信息构成

Version 数据包说明(两个字节)
0x00 0x01

Protocol 协议(一个字节),一共分三种 StreamProtocol、SingleOpProtocol 和 MultiplexProtocol。

分别对应的值如下:
◦StreamProtocol:0x4b
◦SingleOpProtocol:0x4c
◦MultiplexProtocol:0x4d

Messages:数据包说明

针对 Message 的消息体,由与上面的 Protocal 协议类型指定相关。

如果是 SingleOpProtocol 则消息体只包含一条消息。一般用于 HTTP 方式请求。

The Messages are wrapped within a particular protocol as specified by Protocol. For the SingleOpProtocol, there may only be one Message after the Header, and there is no additional data that the Message is wrapped in. The SingleOpProtocol is used for invocation embedded in HTTP requests, where interaction beyond a single request and response is not possible.


SingleOpProtocol 和 MultiplexProtocol 消息则需要服务器返回 0x4e 字节作为响应。

Message 的类型包含以下三种:
1.Call 表示 RMI 的调用操作
2.Ping 是检测服务是否运行正常
3.DgcAck 当客户端收到服务端的对象消息后告诉服务器可以把返回值对象进行 gc 操作。

Call 消息数据内容:
0x50 CallData

Ping 消息数据内容:
0x52

DgcAck 消息数据内容:
0x54 UniqueIdentifier

CallData:RMI 方法请求数据包
ObjectIdentifier Operation Hash Arguments(可选)

◦ObjectIdentifier (the target of the call)


◦Operation (a number representing the method to be invoked)


◦Hash (a number that verifies that client stub and remote object skeleton use the same stub protocol)


◦Arguments(a list of zero or more Arguments for the call)


UniqueIdentifier 数据包内容(一个字节)
Number Time Count

Arguments:Values 对象
Object

HttpMessage:数据包说明
HttpPostHeader Header Message

HttpPosteHeader 是 HTTP 标准的请求 Header

Header 头和 Message 数据包与上相同。

输入流数据包格式


输入流数据包的内容有以下三个方式:

ReturnData is the result of a "normal" RMI call

An HttpReturn is a return result from an invocation embedded in the HTTP protocol

A PingAck is the acknowledgment for a Ping message

ReturnData 数据包:
0x4e Returns

Returns 数据包,包含 ReturnData 和 PingAck。

ReturnData 数据包:
0x51 ReturnValue

PingAck 数据包:
0x53

ProtocolNotSupported 数据包:
0x4f

ReturnValue:返值数据包结构
0x01 UniqueIdentifier 返回值对象(可选)
0x02 UniqueIdentifierException 对象

Note - ObjectIdentifier, UniqueIdentifier, and EndpointIdentifier are not written out using default serialization, but each uses its own special write method (this is not the writeObject method used by object serialization); the write method for each type of identifier adds its component data consecutively to the output stream.

在使用 RMI 发布服务时,会使用到两个端口。

一个是 RegisterPort,这个是 RMI 的服务注册端口,通过以下 API 来指定。而且服务注册端口必须要指定,默认使用 1099 端口。
Registry reg = LocateRegistry.getRegistry(registryPort);

注册端口是客户端服务连接的端口。

一个是 ServicePort,这个是 RMI 的服务的数据传输端口。该端口是真正在 RMI 客户端与服务端进行数据通信交互的端口。是由注册端口发现有客户端连接后,进行后续分配的端口。默认值为 0 表示使用匿名随机端口。

API 的指定方式如下:
UnicastRemoteObject.exportObject(this.exportedObject, this.servicePort);

[/quote]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值