分布式架构学习(六)-网络通信以及RPC介绍

Scroll Down

分布式架构学习(六)-RPC基本介绍

在分布式服务架构下,各个服务之间都是需要通过网络通信来传输数据,网络通信就是将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可以理解为存根

45366c44f775abfd0ac3b43bccc1abc3_720w

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

RPC通信过程:

image-20200702171153628

  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框架了。