# 分布式架构学习(六)-RPC基本介绍
[TOC]
在分布式服务架构下,各个服务之间都是需要通过网络通信来传输数据,网络通信就是将A主机的数据通过**协议**将报文从A主机传输到B主机上。其中传输协议比较出名的有tcp、udp等等,tcp、udp都是在基于Socket概念上为某类应用场景而扩展出的传输协议,网络IO,主要有bio、nio、aio三种方式,所有的分布式应用通讯都基于这个原理而实现,只是为了应用的易用,各种语言通常都会提供一些更为贴近应用易用的应用层协议。
## 什么是RPC
RPC 的全称是 Remote Procedure Call,即远程过程调用。简单解读字面上的意思,远程肯定是指要跨机器而非本机,所以需要用到网络编程才能实现。
网络通信的编程一般都比较复杂,而RPC框架核心就是RPC 的作用就是体现在这样两个方面:
- 屏蔽远程调用和本地调用的区别,就类似于调用本地的方法
- 隐藏底层网络通信的复杂性,可以专注于业务逻辑扩展
### RPC通信过程
**RPC需要处理的问题:**
- RPC是一个远程调用,那么网络通信首先就需要使用协议来进行通信,RPC一般默认采用TCP协议来进行传输,因为TCP协议是面向连接的,具有可靠性。
- 两个服务之间需要寻址,A主机调用接口,如果能知道访问的是B主机的相应服务呢,所以需要RPC框架处理如何连接B主机,端口号是什么,方法名称是什么,参数类型是什么,这样RPC框架通过类似于注册中心的机制,查找到对应的B主机相应接口
- 网络传输的数据底层都是通过物理层将数据转换为二进制进行传递,但是调用方与接收方的参数都是对象,对象是无法直接在网络中进行传输的,所以我们需要引入**序列化**的概念,将二进制的数据转换为对象,调用时将对象转换为二进制数据,接收时将二进制数据转换为对象
- 完成真正的方法调用之后将执行结果序列化后,回写到对应的 TCP 通道里面。调用方获取到应答的数据包后,再反序列化成应答对象,这样调用方就完成了一次 RPC 调用。
**RPC核心组件**:
一个RPC框架需要的核心组件有4个,Client,Client stub,Server 以及Server stub,这个Stub可以理解为存根

- **Client(客户端)**:服务的调用方
- **Client Stub(客户端存根)**:存放服务端的地址消息,再将客户端的请求单数打包成网络消息,然后通过网络远程发送给服务方
- **Server(服务端)**:服务提供者
- **Server Stub(服务端存根)**:接收客户端发送的消息,将消息解包并调用本地的方法
**RPC通信过程:**

1. Client用调用本地的接口方式调用接口
2. Client stub将客户端的方法,参数序列化为二进制数据
3. Client通过sockets将消息发送给服务端
4. Server stub收到消息后将数据反序列化
5. Server stub根据反序列化的结果调用服务端的具体服务
6. Server 将接口调用结果返回给服务端存根
7. Server stub将返回结果序列化
8. Server通过sockets将消息返回给客户端
9. Client stub收到消息后,将数据进行反序列化
10. Client得到最终的结果
## 既然有了Http,为什么还要使用RPC呢?
**Http的优势:**
- 无需像RPC的复杂配置
- 不需要引入RPC框架包
- 很轻易实现地跨语言
**Http的缺点**:
- 每次请求都需要携带大量的Http请求头,浪费传输的资源
- 参数与返回值需要进行二次解析
- 不方便管理
**RPC和HTTP请求的区别?**
RPC是一种理念,即远程过程调用,而REST就是一种常用的rpc,只是没有像我们正常使用的RPC框架需要进行配置等内容。RPC可以直接建立在tcp之上,也可以建立在http协议之上,所以普通的Http请求也可以称为RPC,只是与我们常理解的RPC有点不同。
成熟的rpc库相对http请求,更多的是封装了“服务发现”,"负载均衡",“熔断降级”一类面向服务的高级特性。rpc框架是面向服务的更高级的封装。如果把一个http servlet容器上封装一层服务发现和函数代理调用,那它就已经可以做一个rpc框架了。
分布式架构学习(六)-网络通信以及RPC介绍