# 什么是 RPC?
# Republic of People of China
咳咳。。。。下面进入正题。。。。。
# RPC介绍
远程过程调用(Remote Procedure Call,缩写为 RPC)是一个计算机通信协议。 该协议允许运行于一台计算机的程序调用另一台计算机的子程序,而程序员无需额外地为这个交互作用编程。 如果涉及的软件采用面向对象编程,那么远程过程调用亦可称作远程调用或远程方法调用,比如 Java RMI。
有关RPC的想法至少可以追溯到1976年以“信使报”(Courier)的名义使用。RPC首次在UNIX平台上普及的执行工具程序是SUN公司的RPC(现在叫ONC RPC)。它被用作SUN的NFC的主要部件。ONC RPC今天仍在服务器上被广泛使用。 另一个早期UNIX平台的工具是“阿波罗”计算机网络计算系统(NCS),它很快就用做OSF的分布计算环境(DCE)中的DCE/RPC的基础,并补充了DCOM。
远程过程调用是一个分布式计算的客户端-服务器(Client/Server)的例子,它简单而又广受欢迎。 远程过程调用总是由客户端对服务器发出一个执行若干过程请求,并用客户端提供的参数。执行结果将返回给客户端。 由于存在各式各样的变体和细节差异,对应地派生了各式远程过程调用协议,而且它们并不互相兼容。
为了允许不同的客户端均能访问服务器,许多标准化的 RPC 系统应运而生了。其中大部分采用接口描述语言(Interface Description Language,IDL),方便跨平台的远程过程调用。
有些实现扩展了远程调用的模型,实现了双向的服务调用,但是不管怎样,调用过程还是由一个客户端发起,服务器端提供响应,基本模型没有变化。
服务的调用过程为:
1. client调用client stub,这是一次本地过程调用
2. client stub将参数打包成一个消息,然后发送这个消息。打包过程也叫做 marshalling
3. client所在的系统将消息发送给server
4. server的的系统将收到的包传给server stub
5. server stub解包得到参数。 解包也被称作 unmarshalling
6. 最后server stub调用服务过程. 返回结果按照相反的步骤传给client
*****
# 深入理解RPC——你看或没看见 它都在那里
## 什么是 RPC ?
RPC (Remote Procedure Call)即远程过程调用,是分布式系统常见的一种通信方法,已经有 40 多年历史。当两个物理分离的子系统需要建立逻辑上的关联时,RPC 是牵线搭桥的常见技术手段之一。除 RPC 之外,常见的多系统数据交互方案还有分布式消息队列、HTTP 请求调用、数据库和分布式缓存等。
![](https://pic4.zhimg.com/80/v2-e6880f3aeaf89468f2d4e72f97826f85_hd.jpg)
其中 RPC 和 HTTP 调用是没有经过中间件的,它们是端到端系统的直接数据交互。HTTP 调用其实也可以看成是一种特殊的 RPC,只不过传统意义上的 RPC 是指长连接数据交互,而 HTTP 一般是指即用即走的短链接。
RPC 在我们熟知的各种中间件中都有它的身影。Nginx/Redis/MySQL/Dubbo/Hadoop/Spark/Tensorflow 等重量级开源产品都是在 RPC 技术的基础上构建出来的,我们这里说的 RPC 指的是广义的 RPC,也就是分布式系统的通信技术。RPC 在技术中的地位好比我们身边的空气,它无处不在,但是又有很多人根本不知道它的存在。
## Nginx 与 RPC
Ngnix 是互联网企业使用最为广泛的代理服务器。它可以为后端分布式服务提供负载均衡的功能,它可以将后端多个服务地址聚合为单个地址来对外提供服务。如图,Django 是 Python 技术栈最流行的 Web 框架。
![](https://pic1.zhimg.com/80/v2-32846c06a76d1dd5b223e19ba2699c5d_hd.jpg)
Nginx 和后端服务之间的交互在本质上也可以理解为 RPC 数据交互。也许你会争辩说 Nginx 和后端服务之间使用的是 HTTP 协议,走的是短连接,严格上不能算是 RPC 调用。
![](https://pic2.zhimg.com/80/v2-901e0cee67883bbc28e3b731c057b173_hd.jpg)
你说的没错,不过 Nginx 和后端服务之间还可以走其它的协议,比如 uwsgi 协议、fastcgi 协议等,这两个协议都是采用了比 HTTP 协议更加节省流量的二进制协议。如上图所示,uWSGI 是著名的 Python 容器,使用它可以启动 uwsgi 协议的服务器对外提供服务。
uwsgi 通讯协议在 Python 语言体系里使用非常普遍,如果一个企业内部使用 Python 语言栈搭建 Web 服务,那么他们在生产环境部署 Python 应用的时候不是在使用 HTTP 协议就是在使用 uwsgi 协议来和 Nginx 之间建立通讯。
![](https://pic1.zhimg.com/80/v2-4feba5992acb3a4f12f35af447e5d042_hd.jpg)
Fastcgi 协议在 PHP 语言体系里非常常见,Nginx 和 PHP-fpm 进程之间一般较常使用 Fastcgi 协议进行通讯。
## Hadoop 与 RPC
在大数据技术领域,RPC 也占据了非常重要的地位。大数据领域广泛应用了非常多的分布式技术,分布式意味着节点的物理隔离,隔离意味着需要通信,通信意味着 RPC 的存在。大数据需要通信的量比业务系统更加庞大,所以在数据通信优化上做的更深。
![](https://pic3.zhimg.com/80/v2-8784107236c96755c6958a8955d7174f_hd.jpg)
比如最常见的 Hadoop 文件系统 hdfs,一般包括一个 NameNode 和多个 DataNode,NameNode 和 DataNode 之间就是通过一种称为 Hadoop RPC 的二进制协议进行通讯。
## TensorFlow 与 RPC
在人工智能领域,RPC 也很重要,著名的 TensorFlow 框架如果需要处理上亿的数据,就需要依靠分布式计算力,需要集群化,当多个分布式节点需要集体智慧时,就必须引入 RPC 技术进行通讯。Tensorflow Cluster 的 RPC 通讯框架使用了 Google 内部自研的 gRPC 框架。
![](https://pic4.zhimg.com/80/v2-66b0977952f27d32b5c24059e4f448ab_hd.jpg)
## HTTP 调用其实也是一种特殊的 RPC
HTTP1.0 协议时,HTTP 调用还只能是短链接调用,一个请求来回之后连接就会关闭。HTTP1.1 在 HTTP1.0 协议的基础上进行了改进,引入了 KeepAlive 特性可以保持 HTTP 连接长时间不断开,以便在同一个连接之上进行多次连续的请求,进一步拉近了 HTTP 和 RPC 之间的距离。
![](https://pic3.zhimg.com/80/v2-9d6fbe0a12edd062bbf4c8c502e935ed_hd.jpg)
当 HTTP 协议进化到 2.0 之后,Google 开源了一个建立在 HTTP2.0 协议之上的通信框架直接取名为 gRPC,也就是 Google RPC,这时 HTTP 和 RPC 之间已经没有非常明显的界限了。所以在后文我们不再明确强调 RPC 和 HTTP 请求调用之间的细微区别了,直接统一称之为 RPC。
![](https://pic3.zhimg.com/80/v2-93def434e04ef811ba527dff0ad881ae_hd.jpg)
## HTTP VS RPC (普通话 VS 方言)
HTTP 与 RPC 的关系就好比普通话与方言的关系。要进行跨企业服务调用时,往往都是通过 HTTP API,也就是普通话,虽然效率不高,但是通用,没有太多沟通的学习成本。但是在企业内部还是 RPC 更加高效,同一个企业公用一套方言进行高效率的交流,要比通用的 HTTP 协议来交流更加节省资源。整个中国有非常多的方言,正如有很多的企业内部服务各有自己的一套交互协议一样。虽然国家一直在提倡使用普通话交流,但是这么多年过去了,你回一趟家乡探个亲什么的就会发现身边的人还是流行说方言。
如果再深入一点说,普通话本质上也是一种方言,只不过它是官方的方言,使用最为广泛的方言,相比而言其它方言都是小语种,小语种之中也会有几个使用比较广泛比较特色的方言占比也会比较大。这就好比开源 RPC 协议中 Protobuf 和 Thrift 一样,它们两应该是 RPC 协议中使用最为广泛的两个。
在此我向大家推荐一个Java高级群 :**725633148**里面会分享一些资深架构师录制的视频录像:(有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化、分布式架构)等这些成为架构师必备的知识体系 进群马上免费领取,目前受益良多!
## 换个角度看世界
如果两个子系统没有在网络上进行分离,而是运行在同一个操作系统实例之上的两个进程时,它们之间的通信手段还可以更加丰富。除了以上提到的几种分布式解决方案之外,还有共享内存、信号量、文件系统、内核消息队列、管道等,本质上都是通过操作系统内核机制来进行数据和消息的交互而无须经过网络协议栈。
但在现代企业服务中,这种单机应用已经非常少见了,因为单机应用意味着单点故障 —— “一人摔跤全家跌倒”。业务子系统往往都需要经物理网络栈进行隔离,因此分布式解决方案在要求高可用无间断服务的企业环境里便大有作为,这也让 RPC 迎来自己大放异彩的时代。
前文提到的分布式子系统交互方案,除了 RPC 技术之外还有数据库、消息队列和缓存。但其实这三者本质上是 RPC 技术的一个应用组合。我们可以将数据库服务理解为下面这张图:
![](https://pic1.zhimg.com/80/v2-787ba40b5368510b850adaf6e6cd8f57_hd.jpg)
可以看出,子系统和数据库之间的交互也是通过 RPC 进行的,只不过这里是三个子系统之间复杂的组合消息交互罢了。如果再深入进去,你会发现,这里的数据库不是那种单机数据库,而是具备主从复制功能的数据库,比如 MySQL。在互联网企业里一般都会使用这种主从读写分离的数据库。一个业务子系统将数据写往主库,主库再将数据同步到从库,然后另一个业务子系统又从从库里将数据取出来。这时又可以进一步将它们看成是四个子系统之间进行的更加复杂的 RPC 数据交互。
![](https://pic4.zhimg.com/80/v2-8344989034998b3f845a80d4e853d8de_hd.jpg)
## 小结
现在,读者应该可以深刻理解 RPC 在互联网企业技术中的重要地位。从技术复杂性角度,也应该可以明白为什么说对 RPC 技术的理解水平是评判一个程序员是不是高级程序员的重要标准之一。
- 前言
- 服务器开发设计
- Reactor模式
- 一种心跳,两种设计
- 聊聊 TCP 长连接和心跳那些事
- 学习TCP三次握手和四次挥手
- Linux基础
- Linux的inode的理解
- 异步IO模型介绍
- 20个最常用的GCC编译器参数
- epoll
- epoll精髓
- epoll原理详解及epoll反应堆模型
- epoll的坑
- epoll的本质
- socket的SO_REUSEADDR参数全面分析
- 服务器网络
- Protobuf
- Protobuf2 语法指南
- 一种自动反射消息类型的 Protobuf 网络传输方案
- 微服务
- RPC框架
- 什么是RPC
- 如何科学的解释RPC
- RPC 消息协议
- 实现一个极简版的RPC
- 一个基于protobuf的极简RPC
- 如何基于protobuf实现一个极简版的RPC
- 开源RPC框架
- thrift
- grpc
- brpc
- Dubbo
- 服务注册,发现,治理
- Redis
- Redis发布订阅
- Redis分布式锁
- 一致性哈希算法
- Redis常见问题
- Redis数据类型
- 缓存一致性
- LevelDB
- 高可用
- keepalived基本理解
- keepalived操做
- LVS 学习
- 性能优化
- Linux服务器程序性能优化方法
- SRS性能(CPU)、内存优化工具用法
- centos6的性能分析工具集合
- CentOS系统性能工具 sar 示例!
- Linux性能监控工具集sysstat
- gdb相关
- Linux 下如何产生core文件(core dump设置)