RPC必知必会

目录

一 RPC是什么

二 RPC整体流程

2.1 请求部分

2.2 响应部分

三 RPC序列化

3.1 为什么需要序列化

3.2 序列化方式

3.3  如何选择序列化方式

四 RPC网络通信

4.1 阻塞IO(blocking IO)

4.2 IO 多路复用(IO multiplexing)

4.3 RPC如何选择IO模型


一 RPC是什么

RPC的全称是 Remote Procedure Call,即远程过程调用。

什么是远程调用本地服务调用远程服务。

什么是RPCRPC是帮助我们屏蔽网络编程细节,实现调用远程方法就像调用本地方法一样。

总结来讲,RPC作用有两个:

  • 屏蔽远程调用跟本地调用的区别,让我们感觉就是调用项目内的方法;
  • 隐藏底层网络通信的复杂性,让我们更专注于业务逻辑。

二 RPC整体流程

 RPC通信流程主要是两部分:请求部分和响应部分。

2.1 请求部分

客户端请求API,首先进行序列化、编码,然后网络传输;服务端收到请求,进行解码、反序列化得到客户端请求。

2.2 响应部分

服务端得到客户端请求,进行业务逻辑处理,将结果进行序列化、编码,然后网络传输;客户端收到响应,进行解密、反序列化,得到响应结果。

其中序列化和反序列化模块、编解码、网络传输模块都是通过动态代理实现的。

三 RPC序列化

3.1 为什么需要序列化

RPC调用中,客户端调用服务端是通过网络传输的,而网络传输的数据必须是二进制。

客户端调用方法的时候出入参数都是对象,对象是不能在网络中传输的,需要转成二进制,并且要求转换算法是可逆的,这个过程被称作序列化

服务端收到请求,根据请求类型和序列化类型,将二进制消息转换成请求对象的过程被称作反序列化

序列化就是将对象转换成二进制数据的过程;反序列就是反过来将二进制转换为对象的过程。

3.2 序列化方式

3.2.1 JDK 原生序列化

Java 默认提供的序列化机制,需要序列化的Java对象只需要实现 Serializable / Externalizable 接口并生成序列化ID,这个类就能够通过 ObjectInput 和 ObjectOutput 序列化和反序列化。

JDK 原生序列化几个缺点:

  • 无法跨语言:Java 序列化后的字节数组,其它语言无法进行反序列化。

  • 序列化后的码流太大::相对于目前主流的序列化协议,Java 序列化后的码流太大。

  • 序列化的性能差:由于 Java 序列化采用同步阻塞IO,相对于目前主流的序列化协议,它的效率非常差。

3.2.2 JSON 序列化

JSON ( JavaScript Object Notation) 是一种轻量级的数据交换格式。

优点

  • 前后兼容性高

  • 数据格式比较简单,易于读写

  • 序列化后数据较小,可扩展性好,兼容性好

  • 与XML相比,其协议比较简单,解析速度比较快。

缺点

  • 数据的描述性比 XML 差。

  • 不适合性能要求为 ms 级别的情况。

  • 额外空间开销比较大。

3.2.3 Protobuf 序列化

Protobuf  是 Google 公司内部的混合语言数据标准,是一种轻便、高效的结构化数据存储格式,可以用于结构化数据序列化,支持 Java、Python、C++、Go 等语言。Protobuf 使用的时候需要定义 IDL(Interface description language),然后使用不同语言的 IDL 编译器,生成序列化工具类。

优点

  • 序列化后体积相比 JSON 小很多;

  • IDL 能清晰地描述语义,所以足以帮助并保证应用程序之间的类型不会丢失,无需类似 XML 解析器;

  • 序列化反序列化速度很快,不需要通过反射获取类型;

  • 消息格式升级和兼容性不错,可以做到向后兼容。

缺点:

  • 不支持 null。

  • Protobuf 不支持单纯的 Map、List 集合对象,需要包在对象里面。

3.2.4 xml 序列化

XML(Extensible Markup Language)是一种常用的序列化和反序列化协议。

优点

  • 人机可读性好

  • 可指定元素或特性的名称

缺点

  • 序列化数据只包含数据本身以及类的结构,不包括类型标识和程序集信息。

  • 类必须有一个将由 XmlSerializer 序列化的默认构造函数。

  • 只能序列化公共属性和字段

  • 不能序列化方法

  • 文件庞大,文件格式复杂,传输占带宽

使用场景

  • 当做配置文件存储数据

  • 实时数据转换

3.2.5 Thrift 序列化

Thrift 并不仅仅是序列化协议,而是一个 RPC 框架。它可以让你选择客户端与服务端之间传输通信协议的类别,即文本(text)和二进制(binary)传输协议, 为节约带宽,提供传输效率,一般情况下使用二进制类型的传输协议。

优点

  • 序列化后的体积小, 速度快。

  • 支持多种语言和丰富的数据类型。

  • 对于数据字段的增删具有较强的兼容性。

  • 支持二进制压缩编码。

缺点

  • 使用者较少。

  • 跨防火墙访问时,不安全。

  • 不具有可读性,调试代码时相对困难。

  • 不能与其他传输层协议共同使用(例如HTTP)。

  • 无法支持向持久层直接读写数据,即不适合做数据持久化序列化协议。

适用场景

  • 分布式系统的RPC解决方案

3.3  如何选择序列化方式

在 RPC 框架中我们选择序列化方式,需要考虑性能、效率、空间开销、通用性、兼容性、安全性等多个因素。

性能和效率

序列化和反序列化是 RPC 调用必须经历的过程,序列化和反序列化方式的性能和效率越好,RPC 框架整体性能和效率越高。

空间开销

所谓的空间开销就是序列化之后的二进制数据的体积大小。序列化后的字节数据越小,网络传输的数据量就越小,传输数据的速度也就越快。网络传输速度直接影响到请求响应的耗时。

通用性和兼容性

在序列化的选择上,与序列化协议的效率、性能、空间开销相比,通用性和兼容性的优先级会更高,因为直接关系到服务调用的稳定性和可用率的,对于服务的性能来说,服务的可靠性显然更加重要。

我们更加看重这种序列化协议在版本升级后的兼容性是否很好,是否支持更多的对象类型,是否是跨平台、跨语言的,是否有很多人已经用过并且踩过了很多的坑,其次我们才会去考虑性能、效率和空间开销。

安全性

安全性应该是非常重要的一个参考因素,需要优先级最高去考虑,如果说序列化方式存在安全漏洞,线上的服务很可能被入侵。

各个因素优先级从高到低:

安全性 > 通用性 > 兼容性 > 性能 > 效率 > 空间开销

上面几种序列化方式推荐的是 Protobuf 和 Thrift 两种序列化。

  • Protobuf Protobuf 效率高、通用性强。

  • Thrift 兼容性好,通用性强,空间开销小。

四 RPC网络通信

所谓的网络通信,就是网络IO操作。那网络IO有哪些模型呢?常见的网络 IO 模型分为四种:

  • 同步阻塞 IO(BIO)
  • 同步非阻塞 IO(NIO)
  • IO 多路复用
  • 异步非阻塞 IO(AIO)

四种 IO 模型中,只有 AIO 为异步 IO,其他都是同步 IO。最常用的是同步阻塞IO和IO多路复用

4.1 阻塞IO(blocking IO)

在 Linux 中,默认情况下所有的 socket 都是 blocking 的,先看下操作流程。

应用进程发起 IO 系统调用后,应用进程被阻塞,转到内核空间处理。之后,内核开始等待数据报,等待到数据报之后,再将内核中的数据拷贝到用户内存中,整个 IO 处理完毕后返回进程。最后应用的进程解除阻塞状态,运行业务逻辑。

内核处理 IO 操作分为两个阶段:等待数据、数据拷贝。而在这两个阶段中,应用进程中 IO 操作的线程会一直都处于阻塞状态。

4.2 IO 多路复用(IO multiplexing)

多路复用 IO 是在高并发场景中使用最为广泛的一种 IO 模型,如 Java 的 NIO、Redis、Nginx 的底层实现就是此类 IO 模型的应用,经典的 Reactor 模式也是基于此类 IO 模型。

 IO 多路复用怎么理解?多路就是指多个通道,也就是多个网络连接的 IO,而复用就是指多个通道复用在一个复用器上。

如图所示,多个Socket 可以注册到一个IO多路复用程序上,一旦Socket注册到IO多路复用程序上,那么整个进程会被阻塞。内核会“监视”所有IO多路复用程序负责的 socket,当任何一个 socket 中的数据准备好了,内核就会对Socket事件进行处理,IO多路复用程序就会返回。这个时候用户进程再调用 read 操作,将数据从内核中拷贝到用户进程。

IO多用复用的优势是,用户可以在一个线程内同时处理多个 socket 的 IO 请求。用户可以注册多个 socket,然后不断地调用 select 读取被激活的 socket,即可达到在同一个线程内同时处理多个 IO 请求的目的。而在同步阻塞模型中,必须通过多线程的方式才能达到这个目的。

4.3 RPC如何选择IO模型

由于RPC调用是一个高并发的场景,IO多路复用比较适合。开发语言的网络通信框架的选型上,我们最优的选择是基于 Reactor 模式实现的框架,如 Java 语言,首选的框架便是 Netty 框架(Java 还有很多其他 NIO 框架,但目前 Netty 应用得最为广泛),并且在 Linux 环境下,也要开启 epoll 来提升系统性能(Windows 环境下是无法开启 epoll 的,因为系统内核不支持)。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值