RPC远程过程调用(Remote Procedure Call)

RPC,就是Remote Procedure Call,远程过程调用

远程过程调用,自然是相对于本地过程调用

本地过程调用,就好比你现在在家里,你要想洗碗,那你直接把碗放进洗碗机,打开洗碗机开关就可以洗了。这就叫本地过程调用

远程过程调用,那就是你现在不在家,突然发现碗还没洗,打了个电话过来,叫我去洗碗,这就是远程过程调用

RPC调用的流程:

  1. 服务消费方(client)调用以本地调用方式调用服务;
  2. client stub接收到调用后负责将方法、参数等组装成能够进行网络传输的消息体;
  3. client stub找到服务地址,并将消息发送到服务端;
  4. server stub收到消息后进行解码;
  5. server stub根据解码结果调用本地的服务;
  6. 本地服务执行并将结果返回给server stub;
  7. server stub将返回结果打包成消息并发送至消费方;
  8. client stub接收到消息,并进行解码;
  9. 服务消费方得到最终结果。

RPC的目标就是要2~8这些步骤都封装起来,让用户对这些细节透明。

RPC消息数据结构

  • 客户端的请求消息结构一般需要包括以下内容:
  1. 接口名称 如果不传,服务端就不知道调用哪个接口
  2. 方法名 一个接口内可能有很多方法
  3. 参数类型&参数值
  4. 超时时间
  5. requestID,标识唯一请求id
  • 服务端返回的消息结构一般包括以下内容
  1. 返回值
  2. 状态code
  3. requestID

    序列化与反序列化

    现如今序列化的方案越来越多,每种序列化方案都有优点和缺点,它们在设计之初有自己独特的应用场景,那到底选择哪种呢?从RPC的角度上看,主要看三点:
  4. 通用性,比如是否能支持Map等复杂的数据结构;
  5. 性能,包括时间复杂度和空间复杂度,由于RPC框架将会被公司几乎所有服务使用,如果序列化上能节约一点时间,对整个公司的收益都将非常可观,同理如果序列化上能节约一点内存,网络带宽也能省下不少;
  6. 可扩展性,对互联网公司而言,业务变化快,如果序列化协议具有良好的可扩展性,支持自动增加新的业务字段,删除老的字段,而不影响老的服务,这将大大提供系统的健壮性。

    一个优秀的RPC框架需要考虑的问题

  • 既然是分布式了,那么一个服务可能有多个实例,你在调用时,要如何获取这些实例的地址
  • 这时候就需要一个服务注册中心,比如在Dubbo里头,就可以使用Zookeeper作为注册中心,在调用时,从Zookeeper获取服务的实例列表,再从中选择一个进行调用
  • 那么怎么调用好呢?这时候就需要负载均衡了,于是你又得考虑如何实现负载均衡,比如Dubbo就提供了好几种负载均衡策略
  • 这还没完,总不能每次调用时都去注册中心查询实例列表吧,这样效率多低呀,于是又有了缓存,有了缓存,就要考虑缓存的更新问题
  • 客户端总不能每次调用完都干等着服务端返回数据吧,于是就要支持异步调用;
  • 服务端的接口修改了,老的接口还有人在用,怎么办?总不能让他们都改了吧?这就需要版本控制了;
  • 服务端总不能每次接到请求都马上启动一个线程去处理吧?于是就需要线程池;
  • 服务端关闭时,还没处理完的请求怎么办?是直接结束呢,还是等全部请求处理完再关闭呢?
  • ......

本文参考文档

猜你喜欢

转载自www.cnblogs.com/Dewumu/p/12205942.html