IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> dubbo原理与核心功能 -> 正文阅读

[网络协议]dubbo原理与核心功能

Dubbo 是一款微服务开发框架,它提供了【RPC通信】与【服务治理】两大关键能力。

RPC远程调用技术

RPC 全称 Remote Procedure Call,是一种进程间通信方式。它允许程序调用另一个地址空间(通常是共享网络的另一台机器上)的过程或函数,而不用程序员显式编码这个远程调用的细节。

RPC是一种抽象的概念,像常见的 RMI、WebService、Http 等是它的具体实现。

dubbo 也对 RPC 做了具体实现,制定了 dubbo协议,默认使用的就是 dubbo协议。

dubbo服务发现基本工作原理

服务发现,即消费端自动发现服务地址列表的能力,是微服务框架需要具备的关键能力,借助于自动化的服务发现,微服务之间可以在无需感知对端部署位置与 IP 地址的情况下实现通信。

实现服务发现的方式有很多种,Dubbo 提供的是一种 Client-Based 的服务发现机制,通常还需要部署额外的第三方注册中心组件来协调服务发现过程,如常用的 Nacos、Zookeeper 等。

工作原理图

其中:Registry表示注册中心、Provider表示服务提供者、Consumer表示服务消费者。

流程说明

  1. Provider绑定指定端口并启动服务
  2. Provider连接Registry,并将{本机IP、端口、应用信息和提供服务信息}发送至Registry存储
  3. Consumer连接Registry ,并发送{应用信息、所求服务信息}至Registry
  4. Registry根据Consumer所求服务信息匹配对应的Provider列表发送至Consumer应用进行缓存
  5. Consumer在发起远程调用时基于缓存的Provider列表择其一发起调用
  6. Provider状态变更会实时通知Registry,再由Registry实时推送至Consumer

优势

  1. Consumer与Provider解偶,双方都可以横向增减节点数
  2. 注册中心本身可做集群,可动态增减节点,并且任意一台宕掉后,将自动切换到另一台
  3. 去中心化,双方不直接依懒注册中心,即使注册中心全部宕机短时间内也不会影响服务的调用(Consumer本地缓存Provider列表)
  4. 服务提供者无状态,任意一台宕掉后,不影响使用

dubbo调用模块原理

dubbo调用模块涉及透明代理、负载均衡、容错机制、调用方式等。

调用流程:

透明代理

通过动态代理技术,屏蔽远程调用细节以提高编程友好性。

客户端在启动时,创建bean的过程中,会给接口创建代理对象。代码是在ReferenceConfig的createProxy方法中。

默认使用Javassist来实现动态代理。使用的类是JavassistProxyFactory。

编程的时候像本地调用接口一样,但实际调用时通过代理对象来操作,通过代理对象调用时可以远程调用。

容错机制

dubbo支持多种容错机制(默认Failover):

容错机制说明

失败自动切换(Failover)

失败自动切换,当出现失败,重试其它服务器。通常用于读操作,但重试会带来更长延迟。可通过 retries="2" 来设置重试次数(不含第一次)。

快速失败(Failfast)

快速失败,只发起一次调用,失败立即报错。通常用于非幂等性的写操作,比如新增记录。

失败安全(Failsafe)

失败安全,出现异常时,直接忽略。通常用于写入审计日志等操作。

失败自动恢复(Failback)失败自动恢复,后台记录失败请求,定时重发。通常用于消息通知操作。
并行调用(Forking)并行调用多个服务器,只要一个成功即返回。通常用于实时性要求较高的读操作,但需要浪费更多服务资源。可通过 forks="2" 来设置最大并行数。
广播调用(Broadcast)广播调用所有提供者,逐个调用,任意一台报错则报错。通常用于通知所有提供者更新缓存或日志等本地资源信息。
其他......

以 Failover 机制为例,源码是在 FailoverClusterInvoker 中,如果 retries="2",那么最多尝试调用3次。代码中就是循环3次,只要成功,立刻return。

负载均衡

Dubbo支持以下几种负载均衡策略,默认为【加权随机】:

策略说明
加权随机(Random)按权重设置随机概率。默认权重相同。
加权轮循?(RoundRobin)按公约后的权重设置轮询比率,循环调用节点。默认权重相同。
加权最少活跃调用优先(LeastActive)活跃数越低,越优先调用,相同活跃数的进行加权随机。
加权最短响应优先(ShortestResponse)在最近一个滑动窗口中,响应时间越短,越优先调用。相同响应时间的进行加权随机。
一致性哈希(ConsistentHash)相同参数的请求总是发到同一提供者。

客户端启动时,会调用Protocol的refer方法,来引用服务,最终实现是在DubboProtocol的protocolBindingRefer方法中,获取服务提供者列表,缓存起来(Set<Invoker<?>> invokers)。

当调用时,从缓存中根据负载均衡策略,取出一个服务提供者。

代码中,进行负载均衡是在 FailoverClusterInvoker(以Failover容错策略为例)的 doInvoke 中调用的,具体实现是在 AbstractClusterInvoker 的 doSelect() 方法中。

调用方式

默认调用方式为:异步调用,同步等待结果返回。也就是“异步转同步”。

从 version 2.7.0 开始,Dubbo 的所有异步编程接口开始以 CompletableFuture 为基础。

接口返回的是一个 AsyncRpcResult 对象,这个对象是立即返回的,但是里面并没有实际结果,接口调用未结束。

之后会调用 AsyncRpcResult 的 get 方法尝试获取实际结果,内部调用了 CompletableFuture 的 waitingGet 方法。在 waitingGet 方法中,通过 while 循环实现阻塞,直到获取实际结果(result)才返回,接口调用结束。以此达到异步转同步的效果。

协议

Dubbo 支持 dubbo、rmi、hessian、http、webservice、thrift 等多种协议。默认使用"dubbo协议"。

"dubbo协议"采用单一长连接和NIO异步通讯,适合于小数据量大并发的服务调用,以及服务消费者机器数大于服务提供者机器数的情况。他不适合传送大数据量的服务,比如传文件,传视频等。

当使用"dubbo协议"时,url以"dubbo://"开头,类似如下这样:

dubbo://127.0.0.1:20880/com.xujingyi.contract.service.UserService

dubbo协议报文编码:

magic2字节

类似java字节码文件里的魔数,用来判断是不是dubbo协议的数据包。

魔数是常量0xdabb,用于判断报文的开始。

flag1字节

标志位, 一共8个地址位。

低四位用来表示消息体数据用的序列化工具的类型(默认hessian);

高四位中,第一位为1表示是request请求,第二位为1表示双向传输(即有返回response),第三位为1表示是心跳ping事件。

status1字节

状态位, 设置请求响应状态,dubbo定义了一些响应的类型。

具体类型见 com.alibaba.dubbo.remoting.exchange.Response

invoke id8字节消息id, long 类型。每一个请求的唯一识别id(由于采用异步通讯的方式,用来把请求request和返回的response对应上)
body length4字节消息体 body 长度, int 类型,即记录Body Content有多少个字节。

dubbo协议编码过程:

远程调用时,假设发送的是一个java对象,但是计算机处理的时候不认java对象、字符串这种,只认字节,所以需要先对消息体进行编码。编码时需要根据协议报文进行。

解码时根据协议报文的格式,解析前16个字节,根据它来准确得获取消息体。比如通过 body length?来确定消息体的长度,防止 Netty?粘包拆包导致获取的消息体不是想要的消息体。

底层通信机制

dubbo 客户端与服务端的通信,底层通过 netty 来实现的。

服务端

dubbo服务端在启动的时候,会通过DubboProtocol中的export方法暴露服务,在其中会创建Netty服务端。具体代码是NettyServer类中的doOpen()方法:

可以看到,这是标准的 Netty 服务端的代码。

Pipeline 中添加了"dubbo协议"的编解码处理器;还有用于处理心跳检测的 IdleStateHandler,负责检测Netty服务端与客户端的连接。

客户端?

dubbo客户端在启动时,会创建Netty客户端,具体代码是NettyClient类中的doOpen()方法:

Pipeline 中添加了"dubbo协议"的编解码处理器,还有用于处理心跳检测的 IdleStateHandler。?

客户端调用接口的时候,最终会调用到dubbo包中NettyChannel的send()方法来进行远程调用。而NettyChannel中的channel对象,就是Netty客户端的NioSocketChannel,通过NioSocketChannel来跟netty服务端进行通信。

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-03-04 15:57:23  更:2022-03-04 15:58:38 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年10日历 -2024/10/5 13:27:27-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码