当前位置:首页 > 公众号精选 > 后端技术指南针
[导读]1 前言 今天来和大家一起学习一下RPC,还是要先声明篇幅所限,本文不会深入展开,所以本文是浅谈。 还是老规矩,秉承 "最基础的也是最重要的,最重要的也是最简单的",不搞那么花哨。 能让对这个事情一无所知但是有相关经验的人员迅速切入重点,掌握轮廓是一

1 前言

今天来和大家一起学习一下RPC,还是要先声明篇幅所限,本文不会深入展开,所以本文是浅谈。

还是老规矩,秉承 "最基础的也是最重要的,最重要的也是最简单的",不搞那么花哨。

能让对这个事情一无所知但是有相关经验的人员迅速切入重点,掌握轮廓是一种重要的能力,知道别人会困在哪里,哪些是必要的更是一种思维方式。

一个好的厨师应该也是一个美食家,如果你还是个业务仔,但是想成为架构师,不要着急,懂业务才更懂架构,架构是为业务服务的,纸上谈兵的架构师也造不出好轮子。

个人认为:抽象问题和拆解问题是做好架构和业务的重要能力,在日常工作中要注意两方面的培养。

通过本文你将了解到以下内容:

  • 什么是RPC和为什么需要它
  • RPC的重要组件
  • 常见RPC框架和各自特点

废话不说,开车开车!

图来自网络: 好奇号火星车

2 什么是RPC以及为什么需要它

RPC 是1984年代由 Andrew D. Birrell & Bruce Jay Nelson 提出的,所以并不是最近的概念,在二位大神的论文 "Implementing Remote Procedure Calls" :

Implementing Remote Procedure Calls http://pages.cs.wisc.edu/~sschang/OS-Qual/distOS/RPC.htm

设计目标:

Make distributed computing easy: let the programmer focus on fundamental difficulty of distributed computing: timing, independent failure of components.

Make RPC communication highly efficient: don't distort program by making programmer avoid communication due to its slowness

Make the semantics of RPC as powerful as possible without loss of simplicity or efficiency

Provide secure communication

简单概括就是让分布式系统更加简单,让开发人员把精力放到业务上,并且提供高效安全的通信。

再来看看比较常见的解释,了解下RPC是啥:

RPC(Remote Procedure Call)远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。也就是说两台服务器A,B,一个应用部署在A服务器上,想要调用B服务器上应用提供的方法,由于不在一个内存空间,不能直接调用,需要通过网络来表达调用的语义和传达调用的数据。

大白话理解这段话就是说:RPC让你用别人家的东西就像自己家的一样

听得我似懂非懂,于是我不得不问几个问题:

  • 为啥要用别人家的东西(请求其他服务)
  • 我怎么可以借到别人家的东西(其他服务调用)
  • 要是借用的话哪种形式更好(确定一个合适的调用方法)
  • 怎么让我用别人东西像自己的一样(屏蔽底层细节透明通信)

阐述RPC之前我们必须达到一个 共识问题 :RPC只是一种通信模式,和http并不冲突对立,相反http可以作为RPC传输数据的一种协议,把RPC当作一种模式和思想,我们才能更好地理解它。

2.1 为什么要请求其他服务

典型的B/S模型或者C/S模型都是客户端要调用服务端接口来获取数据和结果,这种属于外部调用。

区别于外部调用,内部系统随着业务规模的扩大,出现了分布式和微服务,简单说就是把一个庞大的业务拆分成很多子服务,并且每个子服务都部署在很多独立分布的机器上,从而形成一个庞大的内部系统。

生活也是如此,自给自足的农耕经济早已经过去,不同的社会分工有不同的公司团体机构,我们要想完成自己的日常就难免和其他单位实体进行交互。

还是举一个例子:比如我们用QQ音乐听歌,感兴趣的歌曲会做成歌单,当手机端用户先用手机号/邮箱/第三方账号等进行登陆,登录之后进入的自己主页,拉取自己喜欢的歌曲歌单,最后点击播放,这个过程就涉及到多个服务的相互调用,如图:


庞大的单体程序好像逐渐没有市场了,取而代之的是拆分之后的诸多独立功能的服务,它们之间必然存在相互调用来实现一个综合的功能。

2.2 如何调用其他服务

在日常业务中我们可以把功能封装成静态库、动态库、sdk、独立服务等,最常见也最方便的还是http这种形式的调用。

http服务把需要提供的服务暴露成接口,使用方直接按约定的http方法和uri进行数据交互。

我们都知道http协议是应用层协议,是个非常标准的协议,在http协议之下还有网络层、传输层、数据链路层等,一个数据包packet除了净荷payload之外还有很多header,由于标准和通用性的设计目标也使得http一次数据交互真正传输的payload只是其中一部分。

图来自网络:http数据包格式


http是我们用的最多最熟悉的交互模式,在系统内部各个服务之间接口较少,交互不多的情况下工作得还不错。


在内部系统调用很复杂的前提下,http调用的效率和安全性就不那么理想了,更重要的是面对众多的服务我们需要的不仅仅是一个通信方式,而是一个内部服务的管理系统,这也就是我们今天说的RPC框架,注意RPC是一种模式策略和框架,并不是单纯的通信协议。

2.3 实现远程调用的一些思路

前面说了RPC远程过程调用就是让服务A像调用本地功能一样调用远端的服务B上的功能,不要把这个事情想的太悬乎,想想我们本地调用时需要哪些东西:确定的类或函数、类或函数的参数、类或函数的返回值

远程调用肯定也不会缺少这三要素,唯一的区别在于这三要素是要被传输过去的,这其中就涉及协议编码和解码的过程。

机器10.1.1.1上部署了服务A,机器10.1.1.2上部署了服务B,并且服务B上有一个add函数,int add(int a,int b),参数是两个int 返回值是int。

这样服务A需要通过网络传输来告诉服务B,它想要add函数,传入的两个参数分别是3和5,返回的结果放在result里面就可以。

传输的报文里面按照约定的协议格式给出了函数名和参数,大致这样:

上述的编码只是一种举例不代表实际应用,旨在说明本地调用和远程调用的唯一区别就是传输基本要素的方式不同,不要想的太复杂。


为了提高传输效率可以进行二进制编码,比如protobuf这种。当然还有其他问题,就不再详细展开了,这些都是我们在设计一个RPC框架时需要考虑的点。

2.4 关于http和RPC的一些辩论

http和rpc是两个很容易混淆的概念,最开始接触rpc的时候,我就在想有http了为什么还要用rpc?  在知乎上看到了这个很有趣的问题:

在知乎上有个很好的问题:既然有http请求,为什么还要用rpc? 详情戳:https://www.zhihu.com/question/41609070

其中一个大佬的回答感觉很有意思:


这个问题的诸多回答其实都表达了一个重要观点:RPC是一种编程模式和概念,并不是非常具体的一种技术,并且和http没有明确的冲突,http可以作为RPC传输协议,更重要的是RPC是一种内部服务框架,可以涉及服务注册、服务治理、服务发现、熔断机制、负载均衡等。

3.典型的RPC框架组件

前面提到了rpc不是简单的一种协议或者技术,而是一种模式和框架,其典型的组成,如图:

图来自网络:rpc典型组成


RPC协议模块是很重要的部分,这部分也是前面提到的服务A调用服务B时传输报文的过程,如图:

图来自网络:rpc协议组成

其中的序列化和反序列化定义:

序列化:将数据结构或对象转换成二进制串的过程。

反序列化:将序列化中所生成的二进制串转换成数据结构或者对象的过程。

在网络消息传输中可以基于TCP、UDP、http来实现,各自都有各自的特点:

基于 TCP 实现的 RPC 调用,能够灵活对协议字段进行定制,减少网络开销提高性能,实现更大的吞吐量和并发数,但要关注底层细节,在进行数据解析时更加复杂一些。

基于 HTTP 实现的 RPC 可以使用 JSON 和 XML 格式的请求或响应数据,解析工具很成熟,在其上进行二次开发会非常便捷和简单。但是 HTTP 是上层协议,所占用的字节数会比使用 TCP 协议传输所占用的字节数更高。

对于其他部分,本文不再展开。

4.常见的RPC框架和各自特点

Dubbo 是阿里巴巴公司开源的一个Java高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和 Spring框架无缝集成。

Motan是新浪微博开源的一个Java 框架。它诞生的比较晚,起于2013年,2016年5月开源。Motan 在微博平台中已经广泛应用,每天为数百个服务完成近千亿次的调用。

rpcx是Go语言生态圈的Dubbo, 比Dubbo更轻量实现了Dubbo的许多特性,借助于Go语言优秀的并发特性和简洁语法,可以使用较少的代码实现分布式的RPC服务。

gRPC是Google开发的高性能、通用的开源RPC框架,其由Google主要面向移动应用开发并基于HTTP/2协议标准而设计,基于ProtoBuf(Protocol Buffers)序列化协议开发,且支持众多开发语言。本身它不是分布式的,所以要实现上面的框架的功能需要进一步的开发。


thrift是Apache的一个跨语言的高性能的服务框架,也得到了广泛的应用,Thrift是Facebook于2007年开发的,它提供多语言的编译功能,通过Thrift的IDL来描述接口函数及数据类型,通过Thrift的编译环境生成各种语言类型的接口文件。

brpc(baidu-rpc)是百度开发一款远过程调用网络框架。目前该项目已在github上开源,brpc目前被应用于百度公司内部各种核心业务上,其中包括高性能计算和模型训练和各种索引和排序服务,且有超过100万以上个实例是基于brpc工作的。

Tars 是腾讯根据内部多年使用微服务架构的实践,总结而成的开源项目,仅支持 C++ 语言,目前在腾讯内部应用也非常广泛。

其中关于brpc在知乎有个很好的问题,其中有包括大神戈君(brpc主导者)在内的多个回答,可以帮助我们快速了解brpc框架:

如何评价百度开源的 RPC 框架 brpc?https://www.zhihu.com/question/65370268

tars和brpc是非常不错的开源项目,尤其作为C++程序员很推荐阅读。

后面一定要写一下gRPC、brpc、tars,先占个坑。

5 巨人的肩膀

  • https://www.w3cschool.cn/architectroad/architectroad-rpc-framework.html

  • https://developer.51cto.com/art/201906/597963.htm

  • https://dubbo.apache.org/zh-cn/blog/rpc-introduction.html

  • https://colobu.com/2016/09/05/benchmarks-of-popular-rpc-frameworks/

  • https://cloud.tencent.com/developer/article/1383845


免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
关闭
关闭