RPC远程过程调用

RPC解决的问题:让分布式或者微服务系统中不同服务之间的调用像本地调用一样简单。
image.png

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

image.png

常见的RPC框架(了解)

  • RMI(JDK自带): JDK自带的RPC,有很多局限性,不推荐使用。
  • Dubbo: Dubbo是 阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和 Spring框架无缝集成。目前 Dubbo 已经成为 Spring Cloud Alibaba 中的官方组件。
  • gRPC :gRPC是可以在任何环境中运行的现代开源高性能RPC框架。它可以通过可插拔的支持来有效地连接数据中心内和跨数据中心的服务,以实现负载平衡,跟踪,运行状况检查和身份验证。它也适用于分布式计算的最后一英里,以将设备,移动应用程序和浏览器连接到后端服务。
  • Hessian: Hessian是一个轻量级的remotingonhttp工具,使用简单的方法提供了RMI的功能。 相比WebService,Hessian更简单、快捷。采用的是二进制RPC协议,因为采用的是二进制协议,所以它很适合于发送二进制数据。
  • Thrift: Apache Thrift是Facebook开源的跨语言的RPC通信框架,目前已经捐献给Apache基金会管理,由于其跨语言特性和出色的性能,在很多互联网公司得到应用,有能力的公司甚至会基于thrift研发一套分布式服务框架,增加诸如服务注册、服务发现等功能。

为什么要用Dubbo

如果要开发分布式程序,可以直接基于HTTP接口进行通信,为什么要用Dubbo呢

  1. 负载均衡:可以将同一个服务器部署在不同机器
  2. 服务调用链路生成:随着系统的发展,服务越来越多,服务间的依赖关系变得错综复杂,Dubbo可以为我们解决服务之间互相是如何调用的。
  3. 服务访问压力以及时长统计、资源调度和治理:基于访问压力实时管理集群容量,提高集群利用率。
  4. 服务降级:某个服务挂掉之后调用备用服务。

Dubbo也可以用在微服务中,但主要还是应用在分布式系统中。

分布式简介

将整个系统拆分成不同的服务然后将这些服务放在不同的服务器上减轻单体服务的压力,提高并发量和性能。比如电商系统可以拆分为订单系统、商品系统、登录系统等,拆分之后可以部署在不同的机器上,如果某一个服务的访问量较大可以将该服务部署在多台服务器上。

Dubbo架构

image.png
调用关系:

  1. 服务容器负责启动,加载,运行服务提供者。
  2. 服务提供者在启动时,向注册中心注册自己提供的服务。
  3. 服务消费者在启动时,向注册中心订阅自己所需的服务。
  4. 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
  5. 服务消费者,从提供者地址列表中,基于负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
  6. 消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。

重要知识点总结:

  • 注册中心负责服务地址的注册与查找,相当于目录服务,服务提供者和消费者只在启动时与注册中心交互,注册中心不转发请求,压力较小
  • 监控中心负责统计各服务调用次数,调用时间等,统计先在内存汇总后每分钟一次发送到监控中心服务器,并以报表展示
  • 注册中心,服务提供者,服务消费者三者之间均为长连接,监控中心除外
  • 注册中心通过长连接感知服务提供者的存在,服务提供者宕机,注册中心将立即推送事件通知消费者
  • 注册中心和监控中心全部宕机,不影响已运行的提供者和消费者,消费者在本地缓存了提供者列表
  • 注册中心和监控中心都是可选的,服务消费者可以直连服务提供者
  • 服务提供者无状态,任意一台宕掉后,不影响使用
  • 服务提供者全部宕掉后,服务消费者应用将无法使用,并无限次重连等待服务提供者恢复

image.png
各层说明

  • 第一层:service层,接口层,给服务提供者和消费者来实现的
  • 第二层:config层,配置层,主要是对dubbo进行各种配置的
  • 第三层:proxy层,服务接口透明代理,生成服务的客户端 Stub 和服务器端 Skeleton
  • 第四层:registry层,服务注册层,负责服务的注册与发现
  • 第五层:cluster层,集群层,封装多个服务提供者的路由以及负载均衡,将多个实例组合成一个服务
  • 第六层:monitor层,监控层,对rpc接口的调用次数和调用时间进行监控
  • 第七层:protocol层,远程调用层,封装rpc调用
  • 第八层:exchange层,信息交换层,封装请求响应模式,同步转异步
  • 第九层:transport层,网络传输层,抽象mina和netty为统一接口
  • 第十层:serialize层,数据序列化层,网络传输需要

Dubbo提供的负载均衡策略

  1. Random LoadBalance:默认策略,基于权重的随机负载均衡。

image.png

  1. RoundRobin LoadBalance:基于权重的轮询负载均衡,不推荐使用,会出现提供者累积请求的问题,比如第二台机器很慢,但没有挂,当请求调到第二台就卡在那,久而久之所有请求都卡在第二台上。

image.png

  1. LeastActive LoadBalance
    活跃调用数指调用前后的计数差,越慢的提供者前后计数差越大。
    活跃调用数越小收到的请求更少,相同活跃数的随机。
  2. ConsistentHash LoadBalance
    一致性Hash,相同参数的请求总是发送到同一提供者。(如果需要的不是随机的负载均衡,是要同一类请求都到一个节点,那就走这个一致性Hash策略。

zookeeper宕机与dubbo直连的情况

如果zookeeper注册中心宕掉,一段时间内服务消费方还是能够调用提供方的服务的,实际上它使用的本地缓存进行通讯。这是dubbo健壮性的一种体现。

dubbo的健壮性表现:

  1. 监控中心宕掉不影响使用,只是丢失部分采样数据。
  2. 数据库宕掉后,注册中心仍能通过缓存提供服务列表查询,但不能注册新服务。
  3. 注册中心对等集群,任意一台宕掉后,将自动切换到另一台。
  4. 注册中心全部宕掉后,服务提供者和服务消费者仍能通过本地缓存通讯。
  5. 服务提供者无状态,任意一台宕掉后,不影响使用。
  6. 服务提供者全部宕掉后,服务消费应用无法使用,并无限次重连等待服务提供者恢复。