在性能基础之浅谈常见接口性能压测 一文中我们有简单介绍常见的 RPC 接口,本文将单篇详细介绍 RPC 协议。
RPC(Remote Procedure Call
)—远程过程调用 ,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC 协议假定某些传输协议的存在,如 TCP 或 UDP,为通信程序之间携带信息数据。在 OSI 网络通信模型中,RPC 跨越了传输层和应用层。
其实简单点的说,就是像调用本地的类的方法样来调用服务器端的方法实现。比如两个不同的服务 A,B 部署在两台不同的机器上,那么服务 A 如果想要调用服务 B 中的某个方法该怎么办呢?使用 HTTP 请求当然可以,但是可能会比较慢而且一些优化做的并不好。 RPC 的出现就是为了解决这个问题。总之,RPC 使得开发分布式程序就像开发本地程序一样简单。
RPC 采用客户端(服务调用方)/服务器端(服务提供方)模式, 都运行在自己的 JVM 中。客户端只需要引入要使用的接口,接口的实现和运行都在服务器端。RPC 主要依赖的技术包括序列化、反序列化和数据传输协议,这是一种定义与实现相分离的设计。
同时需要对 RMI(Remote Method Invoke
,远程方法调用)中的 stub (桩)和skeleton (骨架)的概念有一点了解。RMI 的代理模式是通过代理对象将方法传递给实际对象的。stub 驻留客户端,承担着代理远程对象实现者的角色。skeleton 类帮助远程对象与 stub 连接进行通信。
client stub
接收到调用后负责将方法、参数等组装成能够进行网络传输的消息体;client stub
找到服务地址,并将消息发送到服务端;server stub
收到消息后进行解码;server stub
根据解码结果调用本地的服务;server stub
;server stub
将返回结果打包成消息并发送至调用方;client stub
接收到消息,并进行解码;主要组成元素:
实体对象和业务接口由客户端和服务端公用。
接口实现是由服务端对定义好的业务接口进行功能实现,并将接口实例注册服务中提供给客户端调用。
目前 Java 使用比较多的 RPC 方案主要有RMI(JDK自带)、Hessian、Dubbo、Hprose、Thrift 以及 HTTP 等。
注意: RPC 主要指内部服务之间的调用,RESTful 也可以用于内部服务之间的调用,但其主要用途还在于外部系统提供服务,因此没有将其包含在本知识点内。
Java RMI (Remote Method Invocation
)- 远程方法调用,能够让客户端像使用本地调用一样调用服务端 Java 虚拟机中的对象方法。RMI 是面向对象语言领域对 RPC (Remote Procedure Call)的完善,用户无需依靠 IDL 的帮助来完成分布式调用,而是通过依赖接口这种更简单自然的方式。
Java RMI 是 Java 领域创建分布式应用的技术基石。后续的 EJB 技术,以及现代的分布式服务框架,其中的基本理念依旧是 Java RMI 的延续。在 RMI 调用中,有以下几个核心的概念:
对于第一点,客户端需要依赖接口,而服务端需要提供该接口的实现。
对于第二点,在 J2SE 1.5
版本之前需要通过 rmic 预先编译好客户端的 Stub 对象和服务端的 Skeleton 对象。在之后的版本中,不再需要事先生成 Stub 和 Skeleton 对象。
下面通过示例代码简单的展示 RMI 中的服务注册和发现
Hello obj = new HelloImpl(); // #1
Hello stub = (Hello) UnicastRemoteObject.exportObject(obj, 0); // #2
Registry registry = LocateRegistry.createRegistry(1099); // #3
registry.rebind("Hello", stub); // #4
说明:
UnicastRemoteObject.exportObject
生成可以与服务端通讯的 Stub 对象,Registry registry = LocateRegistry.getRegistry(); // #1
Hello stub = (Hello) registry.lookup("Hello"); // #2
String response = stub.sayHello(); // #3
说明:
理解 RMI 的工作原理和基本概念,对掌握现代分布式服务框架很有帮助,建议进一步的阅读 RMI 官方教材。
Dubbo是 阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和 Spring框架无缝集成。
节点说明:
Hessian是一个轻量级的 remotingonhttp 工具,使用简单的方法提供了RMI的功能。 相比 WebService,Hessian 更简单、快捷。采用的是二进制RPC协议,因为采用的是二进制协议,所以它很适合于发送二进制数据。
Apache Thrift 是 Facebook 开源的跨语言的 RPC 通信框架,目前已经捐献给 Apache 基金会管理,由于其跨语言特性和出色的性能,在很多互联网公司得到应用,有能力的公司甚至会基于 thrift 研发一套分布式服务框架,增加诸如服务注册、服务发现等功能。
详细内容可以参考:性能工具之Jmeter压测Thrift RPC服务
国人开发的一个远程方法调用的开源框架。它是一个先进的轻量级的跨语言跨平台面向对象的高性能远程动态通讯中间件。
详细内容可以参考:性能工具之Jmeter压测Hprose RPC服务
常见于 WEB 应用,基于 HTTP(s) 协议传输文本。当一个 URL发送请求时,服务端 doGet 或者 doPost 方法会被调用,获取相应的参数。压测HTTP接口时,只需要通过定位URL接口并传参,相对比较简单。
现代 RPC 的本质其实就是在网络上传输数据包,而这个数据包的特点是 Header+Body。Header即协议头,分为定长或者变长,这个取决于协议的设计者。例如 dubbo 协议就是定长的。而有些协议是变长的。Body 就是消息体,其实就是对象序列化的过程,把序列化好的数据放入 Body里面。现在流行的序列化方案有 Hessian,java-built-in,JSON,MsgPack,Protobuf等。底层框架一般使用 NIO/Netty 架构,因为是异步通信,需要支持高性能、高并发。
参加文献:
[1]http://jm.taobao.org/2018/06/13/应用/