分类 标签 存档 社区 博客 友链 GitHub 订阅 搜索

Dubbo 专题

270 浏览

ZERO

    持续更新 请关注:https://zorkelvll.cn/blogs/zorkelvll/articles/2018/12/28/1546004534620

背景

     本文主要是记录在学习 Java - Dubbo 过程中的一些知识点备忘!

一、基本概念

1、Dubbo

Dubbo 是一款高性能、轻量级的开源 Java RPC 框架,具有三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。

dubboarchitecturepng

注意:该 dubbo 架构图,需要可以自己手写画出来

说明:

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

2、RPC

RPC 远程过程调用:是一种通过网络从远程计算机程序上请求服务,且不需要了解底层网络技术的通信机制;也即,RPC 是主要是解决远程通信间的问题!

RPC 调用流程图(即 RPC 框架如 dubbo 解决的是第 2~8 步) imagepng

OR 另一种流程图

imagepng

注意:该 RPC 调用流程图,需要可以自己手写画出来

  • step1: 服务消费方 client 调用,以本地调用方式调用服务

  • —- 以下是 RPC 框架 client 功能部分封装的

  • step2:client stub 在接收到调用后,负责将方法、参数等组装成能够进行网络传输的消息体(在 java 中即是序列化过程)

  • step3:client stub 找到服务地址,并将消息发送给服务端

  • —- 以下是 RPC 框架 server 功能部分封装的

  • step4:server stub 收到消息后进行解码(在 java 中即是反序列化过程)

  • step5:server stub 根据解码结果调用本地的服务

  • step6: 本地服务执行并将结果返回给 server stub

  • step7:server stub 将返回结果打包成消息(在 java 中即是序列化过程)并发送至消费方

  • —- 以下是 RPC 框架 client 功能部分封装的

  • step8:client stub 接收到消息,并进行解码(在 java 中即是反序列化过程)

  • step9: 服务消费方最终得到结果

另外,一个时序图如下

imagepng

RPC 框架:即负责屏蔽掉底层的传输方式(TCP 或者 UDP)、序列化方式以及通信细节!如阿里的 HSF、Dubbo,其核心目标是解决分布式系统中服务之间的调用问题

3、RPC 框架技术

3.1 建立通信

在客户端和服务端之间建立 TCP 连接,远程过程调用的所有交换的数据都是在这个连接里传输

3.2 服务寻址
  • 服务注册:将服务注册到服务注册中心,注册中心存储该服务的 IP、端口、调用方式(协议、序列化协议)等(ZK,即是在 ZK 中创建一个 znode 节点进行信息的存储)

  • 服务发现:消费者在第一次调用服务时,会通过注册中心寻找相应服务的 IP 地址列表并缓存在本地,然后直接通过负载均衡算法从 IP 地址列表中取一个服务提供者的服务器调用服务

    3.3 网络传输

    数据传输采用什么协议,数据该如何序列化及反序列化

    3.4 NIO 通信

    大部分 RPC 框架如 Dubbo、HSF、Avro,都是基于 Netty 这个 IO 通信框架的(Netty 是业界流行的 NIO 框架之一,它的健壮性、功能、性能、可定制性和可扩展性在同类框架中都是首屈一指的)

    3.5 服务调用

二、Dubbo 原理

    dubbo 共分为 10 层,其中 service 和 config 层为 API,其余各层均为 SPI(API application programming interface 是给使用者用的,SPI service provider interface 是给扩展者使用的)

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

三、Dubbo 负载均衡

    dubbo 提供多种负载均衡策略,默认为 random 随机调用策略

1、 基于权重的随机负载均衡机制 Random LoadBalance(默认)

  • 随机,根据权重设置随机概率
  • 在一个截面上碰撞的概率很高,但是调用量越大分布越均匀, 且按概率使用权重后也比较均匀,有利于动态调整提供者权重

2、基于权重的轮询负载均衡机制 RoundRobin LoadBalance(不推荐)

  • 轮询,按公约后的权重设置轮询比率
  • 存在慢的提供者累积请求的问题

3、最少活跃调用数 LeastActive LoadBalance

  • 最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差
  • 使慢的提供者收到更少请求,因为越慢的提供者的调用前后计数差会越大

4、一致性 Hash ConsistentHash LoadBalance

  • 一致性 Hash,相同参数的请求总是发到同一提供者(如果需要的不是随机负载均衡,而是要一类请求到一个节点,则应该采用一致性 hash 策略)
  • 当一台提供者挂掉时,原本发往该提供者的请求,基于虚拟节点,会平摊到其他提供者,不会引起剧烈变动
  • 一致性 hash 算法:https://crossoverjie.top/JCSprout/#/algorithm/Consistent-Hash
  • 缺省时只对第一个参数 hash,若需要修改,可配置<dubbo:parameter key="hash.arguments" value="0,1" />
  • 缺省时用 160 份虚拟节点,若需要修改,可配置<dubbo:parameter key="hash.nodes" value="320" />

5、配置方式

  • xml 配置方式:服务端服务级别(dubbo:service loadbalance)、客户端服务级别(dubbo:reference loadbalance)、服务端方法级别(dubbo:service dubbo:method loadbalance)、客户端方法级别(dubbo:reference dubbo:method loadbalance)
  • 注解配置方式:@Service @Reference

四、Dubbo 注册中心 zk

在实际生产中,如果 zk 注册中心宕掉,在一段时间内服务消费方还是能够调用提供方的服务的;这是因为实际上它是使用的本地缓存列表中的服务地址列表信息进行调用的,这也是 dubbo 健壮性的一个方面

dubbo 的健壮性

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

五、相关问题

Dubbo 协议

  • 连接个数:单连接
  • 连接方式:长连接
  • 传输协议:TCP
  • 传输方式:NIO 异步传输
  • 序列化:Hessian
  • 适用范围:入传出参数数据包较小(建议小于 100K),消费者比提供者个数多,单一消费者无法压满提供者,尽量不要用 dubbo 协议传输大文件或超大字符串

评论  
留下你的脚步
推荐阅读