如何理解 RPC(远程过程调用) 及 常用的通信引擎框架

本文详细解析了远程过程调用(RPC)的工作原理,包括函数定位、序列化与反序列化及网络传输等关键技术,并介绍了国内外主流的RPC框架。

简述

远程过程调用(Remote Procedure Call,缩写为RPC),是一种用于构建基于C/S(客户端/服务器)的分布式应用程序的信息传输技术。调用者与被调用者可能在同一台服务器上,也可能在由网络连接的不同服务器上,对于他们来说,网络通信是透明的,远程调用像本地调用一样简单。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。

理解

工作原理:

      运行时,一次客户机对服务器的RPC调用,其内部操作大致有如下十个步骤

1.  调用客户端句柄;执行传送参数

2.  调用本地系统内核发送网络消息

3.  消息传送到远程主机

4.  服务器句柄得到消息并取得参数

5.  执行远程过程

6.  执行的过程将结果返回服务器句柄

7.  服务器句柄返回结果,调用远程系统内核

8.  消息传回本地主机

9.  客户句柄由内核接收消息

10.  客户接收句柄返回的数据

 

RPC就是要像调用本地函数一样去调用远程函数,要理解RPC,让我们先来看看如何完成一个本地函数的调用:

int add(int x,int y)
{
    return x + y;
}

int a = 1;
int b = 1;
int result = add(a,b);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

add函数的执行流程大致为:

  1. 分别将变量a、b的值压入栈
  2. 执行add函数,从栈中取出a、b的值赋值给x、y
  3. 计算x+y的值,并保存在栈中
  4. 退出add函数,将x+y的值赋值给result

本地过程调用发生在同一个进程,共享内存区域,但是RPC通信需要跨过不同的机器,不同的进程,因此需要解决几个问题:

  • 函数ID
  • 序列化、反序列化
  • 网络传输

函数ID

第一个需要解决的问题是如何定位函数的位置,如何告诉远程服务器调用的是哪个函数? 
在本地调用中,通过函数指针来指定函数体,调用add函数,编译器会自动通过函数指针确定add函数在内存中的位置。但是在RPC中,无法通过函数指针来完成调用,因为它们的内存地址可能是完全不同的。所以调用方和被调用方同时需要维护一个{函数<->ID}的映射表,来保证调用到正确的函数。

序列化、反序列化

本地过程调用中传参是通过栈内存结构来实现的,但是RPC并不能直接使用内存来传递参数,因此传输过程中需要把参数或者返回值序列化,转化为字节流,反之为反序列化。

 


image.png | center | 246x224

 

序列化(serialization)是指将数据结构或物件状态转换成可取用格式(例如存成档案,存于缓冲,或经由网络中传送),以留待后续在相同或另一台计算机环境中,能恢复原先状态的过程。

序列化方式的优劣很大程序上影响了RPC的性能,市场上也有很多种序列化方案供选择,如何选择?可以从以下几个角度考虑:

  • 通用性:是否能支持较为复杂的数据结构,如Map等;
  • 性能:序列化所需要的时间以及所占用的空间;
  • 拓展性:是否可以很好的应对公司业务的发展。

网络传输:

函数的调用方和被调用方通常是通过网络连接的,也就是说函数ID、序列化之后的字节流都需要通过网络传输,因此并不局限于某种网络协议,只要可以完成传输即可。比如有的RPC框架使用TCP协议、有的使用HTTP。

对于Java语言来讲,使用IO相关的类库便可以完成网络编程。两种常用的通信模型:BIO与NIO,无论是哪一种模型,实现起来都比较复杂,对程序员要求较高,很有可能会出现隐藏Bug,于是便有了网络通信的编程框架。

Mina和Netty都是Java生态中非常知名的通信框架,它们出自同一个作者:Trustin Lee ,Mina诞生略早,属于Apache基金会,早年火热,如今更新缓慢;而Netty开始在Jboss名下,后来自立门户netty.io,现在大受欢迎,许多RPC框架都基于Netty实现,如阿里的dubbo。

框架

上文中,我们知道实现RPC通信需要解决三个问题,其中序列化、反序列化和网络传输实现的方式多种多样,因此市场上也有着很多种RPC框架。

国内:

  • Dubbo:阿里开源的一款高性能RPC框架,在国内应用广泛,期间停止维护过一段时间,如今又开始了更新,并且捐献给Apache基金会,孵化中;
  • Dubbox:当当团队基于Dubbo升级的一个版本,支持RESTful风格API的远程调用,基于Kryo/FST的Java高效序列化实现等功能,可直接用于生产环境;
  • Motan:新浪微博于2016年开源,“在微博平台中已经广泛应用,每天为数百个服务完成近千亿次的调用”。

国外

  • gRPC:是Google开发的高性能、通用的开源RPC框架,其由Google主要面向移动应用开发并基于HTTP/2协议标准而设计,基于ProtoBuf(Protocol Buffers)序列化协议开发,且支持众多开发语言。本身它不是分布式的,所以要实现上面的框架的功能需要进一步的开发。
  • Thrift:可伸缩的跨语言服务的RPC软件框架,最早由Facebook开发,2007年捐献给了Apache基金会管理,现在是Apache的顶级项目;
  • Finagle:Twitter基于Netty开发的支持容错的、协议无关的RPC框架,支撑了Twitter的核心服务。

我们的开发项目中用到过 ICE ( Internet Communications Engine),由ZeroC公司开发。在进程调用,客户端服务端通信,前端和后端通信,都表现的很稳定。

参考:

1.  百度百科 RPC

2.  https://blog.youkuaiyun.com/u013201439/article/details/81460373

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值