深入理解Dubbo-3.高级功能剖析和原理解析

  • 👏作者简介:大家好,我是爱吃芝士的土豆倪,24届校招生Java选手,很高兴认识大家
  • 📕系列专栏:Spring源码、JUC源码、Kafka原理、分布式技术原理
  • 🔥如果感觉博主的文章还不错的话,请👍三连支持👍一下博主哦
  • 🍂博主正在努力完成2023计划中:源码溯源,一探究竟
  • 📝联系方式:nhs19990716,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬👀

文章目录

  • Dubbo进阶
    • 多序列化支持
    • 性能优化参数
    • Dubbo缓存文件
    • Dubbo是如何实现的
    • Dubbo模块说明
    • Dubbo 流程分析及扩展

Dubbo进阶

对于我们使用这个框架来说,如果会用了以后,更多的可能是需要关心一下为什么要使用这个功能?

它是怎么实现服务的注册,怎么实现服务的发现,以及怎么去动态的更新服务、怎么去负载均衡。

对于一个技术的使用来说,我们可以不去了解这个技术本身原理性的东西就可以去使用了,对于实际的应用开发来说,可能只有项目开始的时候才会去搭建这些技术的整合,配置这些组件和各种工具类等等。搭建好之后,后面大部分的开发都是 ctrl cv的动作,在框架整合来说都是可以复制粘贴的,但是对于业务来说Controller、Service本质上没什么变化。

多序列化支持

Dubbo支持多种序列化方式,包括Hessian、Java原生序列化、JSON、FastJSON、Kryo等。用户可以根据自己的需求选择合适的序列化方式来进行数据交换。这样可以提高系统的灵活性和性能,使得Dubbo可以适应不同的应用场景。

  • 添加jar包支持
<dependency>
	<groupId>com.esotericsoftware</groupId>
	<artifactId>kryo</artifactId>
	<version>4.0.2</version>
</dependency>
<dependency>
	<groupId>de.javakaffee</groupId>
	<artifactId>kryo-serializers</artifactId>
	<version>0.45</version>
</dependency>
  • 添加序列化支持
dubbo.protocol.serialization=kryo

客户端在调用的时候也需要加入以上操作。

多序列化的支持意味着Dubbo可以根据不同的应用场景和需求选择合适的序列化方式,从而提高系统的灵活性和性能。不同的序列化方式有不同的特点,比如Hessian序列化速度快,但占用内存较多;而JSON序列化则占用内存较少,但速度可能稍慢。因此,通过支持多序列化方式,Dubbo可以根据具体情况选择最合适的序列化方式,从而提高系统的性能和效率。另外,支持自定义序列化方式也意味着用户可以根据自己的需求实现自己的序列化方式,从而更好地满足特定的业务需求。因此,多序列化的支持可以使Dubbo更加灵活、高效地应对不同的应用场景和需求。

性能优化参数

dubbo服务里有很多性能优化的参数,这些参数无非就是线程、连接(客户端和服务端建立的连接是长连接还是短连接,是共享连接还是非共享连接)因为这些比较基础的点可能会影响整体的性能。

在这里插入图片描述

对应参数在实际链路中起作用的环节

在这里插入图片描述

首先当客户端发起一个请求的时候,针对每个服务消费者每服务每方法最大并发调用数进行了设置,当超过最大并发数的时候会被拒绝掉,这里是采用一个原子计数器去实现的。

紧接着会对连接数量做限制,这个对于很多的池化的技术组件,比如数据库连接池等都会这样做限制,这个限制本质上就是控制资源的使用。Dubbo协议是长连接协议,当客户端和服务端建立这个连接之后,这个连接不会关,一直会处于一个打开状态,后续的请求如果发现Dubbo里已经有打开的连接,那就用这个连接的通道去进行数据传输。

经过请求之后到了服务端,判断总的连接数是否超过限制。

接着到了线程层面,消耗的是cpu资源,而连接层面消耗的是内存 和 网络通信延迟。其实际的调优就像普遍的线程池调优一样,最后还有executes 对服务提供者每服务每方法最大可并行执行请求数进行限制。

Dubbo缓存文件

配置服务地址的缓存,避免注册中心挂了之后对于服务通信的影响

dubbo.registries.shanghai.zone=shanghai
dubbo.registries.shanghai.weight=100
dubbo.registries.shanghai.file=${user.home}/dubbo_shanghai.cache


dubbo.registries.hunan.address=nacos://192.168.216.128:8848
dubbo.registries.hunan.weight=10
dubbo.registries.hunan.preferred=true
dubbo.registries.hunan.file=${user.home}/dubbo_hunan.cache

Dubbo是如何实现的

对于一个技术的使用来说,使用的多了以后会更加的熟练,但是使用的过程中如果出现了问题,能不能快速的定位到问题,其次就是在用这个技术的时候,能不能去了解其底层是怎么实现的。

在这里插入图片描述

图中左侧蓝色区域表示服务消费者,右侧表示服务提供者,它们都是基于Interface。

消费服务的时候会经过这几个层,首先经过服务层 Service,然后到了配置层Config,该层主要是为了加载Dubbo配置的属性文件。

紧接着到了代理层,其中代理类对进行远程调用,所以代理类要去 Registry 注册层去得到具体要调用哪个服务。

而 Registry 注册层 中 RegistryProtocol 基于注册中心的协议,因为 Registry 层中有不同的注册中心,该层通过 RegistryFactory 去获得注册中心的地址,然后通过 NotifyListener去动态的监听具体要调用哪个服务的地址变化,该地址以目录的方式存储在 RegistryDirectory中,里面存储了多个地址。

然后到了 Cluster 集群层,集群容错是在这里面做的,在 Registry 层拿到地址了需要去调用,调用之前,会进行容错的调用、负载均衡等。LoadBalance是基于上一个环节所拿到的地址,通过LoadBalance 进行 select 之后,这时候得到一个最终的 Invoker (是Dubbo里面的核心机制,可以基于此做远程调用)

此时拿到了 Invoker ,去进行调用,调用的过程中会有一系列的过滤器,形成链式进行过滤,当过滤器链处理完成后会通过协议去处理。

而协议中有个很关键的类叫做 DubboProtocol ,在这里是可以去扩展的,Protocol是一个扩展点,我们在使用的时候在这个扩展点用什么协议取决于 RegistryDirectory 列表中url 中的协议,该url会一直沿着链路传递,直到Protocol来选择要使用的协议,然后进行转发。

转发之后,通过 Exchange 交换层 (该层主要负责服务的通信这一块)

Transport 就是 交换的协议,主要基于Netty,在协议以后要在 Serialize中做序列化 和 反序列化,在这之后,会拿到数据进行处理,最终会去调用我们的服务提供者。


而服务提供者这边,其基于Interface,首先会去发布一个服务(exprot),首先也是先从config 去加载服务端的配置,然后把这个配置信息组装成一个url 去添加到注册中心上,这也是我们能够在zk或者nacos上看到的基于服务发布的注册中心地址的一个原因。

然后紧接着到了 MoiniorFactory ,这里面就是服务监控,然后就是 Exporter 发布了,发布是以什么协议发布出去?同样也会根据当前config里所配置的信息,去选择一个对应的协议去发布。

在我们整个框架中,不管是注册中心也好,不管是LoadBalance也好,其都有一个核心的东西叫做扩展点,其基于SPI的机制进行选择(包含三种扩展点:自适应扩展点、激活扩展点、指定名字的扩展点)

最终发布会通过 Netty Server去注册一个监听。


整体串起来的话,就是客户端去发起请求,会通过前面讲的消费者的链路,最终去调用 服务发布者的 Implement。

Dubbo模块说明

在这里插入图片描述

  • Dubbo-bom 版本管理清单
  • Dubbo-build-tools 版本构建工具
  • Dubbo-cluster 路由层,包含负载均衡、容错等
  • Dubbo-Common 提供一些公共包
  • Dubbo-Compatible 解决兼容问题,解决com.alibaba.dubbo 升级到 org.apache.dubbo所产生的变化,其实就是将一些com.alibaba.dubbo 老的功能单独拎出来
  • Dubbo-Config 加载配置,然后提供统一的对外配置的类
  • Dubbo-ConfigCenter 动态配置中心,通过第三方配置中心来统一管理dubbo的配置
  • Dubbo-Container 容器 Main.main(args) //启动dubbo
  • 启动Dubbo首先加载spring 的配置或者注解, applicationContext=new …();,再去根据配置的信息来启动一个NettServer。
  • Dubbo-Filter 过滤
  • Dubbo-Metadata 元数据(配置数据)
  • Dubbo-Monitor 监控模块(针对服务的调用会产生监控的数据,然后将这些数据上报)
  • Dubbo-Plugin 插件 auth(授权) qos
  • Dubbo-Registry 注册中心
  • Dubbo-Remoting 远程协议支持(包括http、netty)
  • Dubbo-RPC rpc协议/通信的支持
  • Dubbo-Serialization 序列化支持

Dubbo 流程分析及扩展

在这里插入图片描述

此图为上面图的简化版本,纯粹的面向整个调用链去工作的。

其中深绿色部分统一叫做扩展点,Dubbo的每一个点其实都可以扩展。

整个过程还是一样,蓝色部分表示消费者,绿色部分表示服务提供者,这张图的通信部分就更加清晰了。

首先Proxy是生成一个动态代理,动态代理有两种方式 jdk、javassist 这个是可扩展的。

然后是filter 会进行过滤,其中有缓存、权限等,这些过滤主要是针对这些请求里面进行的拦截,其可扩展。

然后就是Invoker,是Dubbo内部封装的对象,其表示远程通信的对象,对Invoker会有 Cluster里面对应的操作,包括failover、failsafe等,当然其本身也是一个扩展点。

然后会去拿到注册中心上的 Directory,其表示的是服务的地址列表,所有的注册中心都是基于 Directory进行交互。

当拿到这个列表以后,会去调用LoadBalance进行负载均衡,其也是可扩展的。

后面又经过Filter,会进行另外一个层次的过滤,比如泛化、计数器、限制等。

接下来就是针对具体远程通信的Invoker,其会根据不同的协议,去发起通信,根据服务端是那种协议,就用那种协议去通信。

然后到了传输层,发起远程通信,其也进行了扩展,可以采用的远程通信有 netty mina,传输层的客户端会建议远程通信,其地址是通过前面在 Directory中在由 LoadBalance 获取到的。

然后根据 codec 进行编码,然后进行 Serialization 序列化。

以上就是在客户端完成的动作。


首先是先线程池,这个在前面的性能优化参数图上能够很好的看出来。

然后是服务这边接收到请求,主要是netty 和 mina,因为前面也是使用这两个进行远程通信,然后就是进行各种协议的处理,最后其服务端也会有一个过滤链。

然后服务端的Invoker在进行一个通信,通过动态代理去完成一个调用,当完成后,在返回。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/233537.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

深入理解JavaScript的箭头函数

深入理解JavaScript的箭头函数 在ES6中&#xff0c;JavaScript引入了箭头函数的概念&#xff0c;它提供了一种更简洁的语法来定义匿名函数。虽然箭头函数看起来很简单&#xff0c;但它们在实际应用中有一些独特的特性和行为。让我们深入理解箭头函数并学习如何正确地使用它们。…

ES6之Map对象

ES6提供了 Map数据结构。它类似于对象&#xff0c;也是键值对的集合。但是“键”的范围不限于字符串&#xff0c;各种类型的值&#xff08;包括对象&#xff09;都可以当作键。 创建方法 let m new Map()console.log(m)Map的方法 1.set( ) 添加元素 接收两个参数&#xff0c…

iMazing 2.17.10官方中文版含2023最新激活许可证码

iMazing是一款iOS设备管理软件&#xff0c;界面简洁功能丰富&#xff0c;但其中还有一个界面更简洁&#xff0c;功能更精炼的小工具&#xff0c;适合轻量级的用户日常来使用&#xff0c;更加方便快捷。接下来&#xff0c;小编就来教大家如何使用iMazing MiNi&#xff0c;以及它…

2-2、基本数据类型

语雀原文链接 文章目录 1、数据类型分类2、基本数据类型2-1、布尔型boolean2-2、字符型char2-3、整型 byte short int long2-4、浮点型float double 3、基本类型转换byte特例char特例 1、数据类型分类 Java 语言是一种强类型语言。通俗点说就是&#xff0c;在 Java 中存储的数…

卡码网 46携带研究材料 LeetCode 416分割等和数组 1049最后一块石头的重量-ii | 代码随想录25期训练营day42、43

动态规划算法4 卡码网 46 携带研究材料 2023.12.6 题目链接常规二维dp数组方法代码随想录讲解[链接]一维滚动数组方法代码随想录讲解[链接] //二维dp数组做法 #include<bits/stdc.h> using namespace std;int main() {//m为材料种类数&#xff0c;n为行李箱最大空间数…

手眼标定 - 最终精度和误差优化心得

手眼标定 - 标定误差优化项 一、TCP标定误差优化1、注意标定针摆放范围2、TCP标定时的点次态与工作姿态尽可能保持相近 二、深度相机对齐矩阵误差1、手动计算对齐矩阵 三、手眼标定拍照姿态1、TCP标定姿态优先2、水平放置棋盘格优先 为减少最终手眼标定的误差&#xff0c;可做或…

首次发布亚马逊云科技生成式AI技术堆栈,re:Invent大会重磅发布

亚马逊云科技总是在不断重构&#xff0c;以推动创新&#xff0c;而今年re:Invent的主角毫无疑问是生成式AI。这从亚马逊云科技副总裁、首席布道师Jeff Barr在re:Invent 2023之前就迫不及待地写了一篇关于PartyRock的体验试玩教程即可窥见一斑。 事实也确实如此。在Las Vegas&am…

什么是HTML?

✨前言✨ 本文主要介绍什么是HTML以及W3C &#x1f352;欢迎点赞 &#x1f44d; 收藏 ⭐留言评论 &#x1f4dd;私信必回哟&#x1f601; &#x1f352;博主将持续更新学习记录收获&#xff0c;友友们有任何问题可以在评论区留言 文章目录 什么是HTMLHTML发展史HTML的特点什么…

编程怎么学才能快速入门,分享一款中文编程工具快速学习编程思路,中文编程工具之分组框构件简介

一、前言&#xff1a; 零基础自学编程&#xff0c;中文编程工具下载&#xff0c;中文编程工具构件之扩展系统菜单构件教程 编程系统化教程链接 https://jywxz.blog.csdn.net/article/details/134073098?spm1001.2014.3001.5502 给大家分享一款中文编程工具&#xff0c;零基础…

Linux权限命令详解

Linux权限命令详解 文章目录 Linux权限命令详解一、什么是权限&#xff1f;二、权限的本质三、Linux中的用户四、linux中文件的权限4.1 文件访问者的分类&#xff08;人&#xff09;4.2 文件类型和访问权限&#xff08;事物属性&#xff09; 五、快速掌握修改权限的做法【第一种…

windows下分卷解压文件

我的文件是这样的&#xff1a; 存放路径为&#xff1a;C:\Users\Luli_study\MICCAI_MMAC\fudanuniversity\DDR dataset 首先要进入分卷文件的目录cd&#xff1a; 第一步&#xff1a;cd /path/o/分卷问文件目录 第二步&#xff1a; 执行之后的结果(红色框出来的)&#xff1a; …

如何掌握构建 LMS 网站的艺术

目录 什么是学习管理系统 (LMS) 在线课程和 LMS 网站的好处 为什么 WordPress 对于 LMS 网站很重要 统一学习中心 多功能性和可扩展性 提高教育参与度 简化管理和监控 节省时间和费用 技能评估和绩效监督 持续学习和技能提升 使用 WordPress 插件构建成功的 LMS 课程 专注于您的…

力扣257. 二叉树的所有路径(递归回溯与迭代)

题目&#xff1a; 给你一个二叉树的根节点 root &#xff0c;按 任意顺序 &#xff0c;返回所有从根节点到叶子节点的路径。 叶子节点 是指没有子节点的节点。 示例 1&#xff1a; 输入&#xff1a;root [1,2,3,null,5] 输出&#xff1a;["1->2->5","…

【小白专用】Sql Server 连接Mysql 更新23.12.09

目标 已知mysql连接参数&#xff08;地址和用户&#xff09;&#xff0c;期望通过Microsoft Sql Server Management Studio &#xff08;以下简称MSSSMS&#xff09;连接Mysql&#xff0c;在MSSSMS中直接查询或修改Mysql中的数据。 一般是选最新的版本下载。 选64位还是32位&a…

java--包装类

1.包装类 ①包装类就是把基本类型的数据包装成对象。 ②自动装箱&#xff1a;基本数据类型可以自动转换为包装类型。 ②自动拆箱&#xff1a;包装类型可以自动转换为基本类型。 2.包装类的其他常见操作 ①可以把基本类型的数据换成字符串类型。 ②可以把字符串类型的数值转…

轻量封装WebGPU渲染系统示例<45>- 材质组装流水线(MaterialPipeline)灯光、阴影、雾(源码)

当前示例源码github地址: https://github.com/vilyLei/voxwebgpu/blob/feature/material/src/voxgpu/sample/MaterialPipelineFog.ts 当前示例运行效果: 此示例基于此渲染系统实现&#xff0c;当前示例TypeScript源码如下&#xff1a; export class MaterialPipelineFog {pr…

9.MySQL 索引

目录 ​​​​​​​概述 概念&#xff1a; 单列索引 普通索引 创建索引 查看索引 删除索引 唯一索引 创建唯一索引 删除唯一索引 主键索引 组合索引 创建索引 全文索引 概述 使用全文索引 空间索引 内部原理 相关算法&#xff1a; hash算法 二叉树算法 …

阿里二面:消息队列的事务消息可以用 TCC 模式实现吗?

大家好&#xff0c;我是君哥。 消息队列的主要功能是系统间解耦&#xff0c;实现流量的削峰填谷。主流的消息队列一般有三个核心操作&#xff1a;消费者发送消息&#xff0c;Broker 保存消息&#xff0c;消费者消费消息。如下图&#xff1a; 对于一个完整的事务消息&#xff0…

【Angular 开发】Angular 信号的应用状态管理

自我介绍 做一个简单介绍&#xff0c;年近48 &#xff0c;有20多年IT工作经历&#xff0c;目前在一家500强做企业架构&#xff0e;因为工作需要&#xff0c;另外也因为兴趣涉猎比较广&#xff0c;为了自己学习建立了三个博客&#xff0c;分别是【全球IT瞭望】&#xff0c;【架构…

基于PaddleOCR银行卡识别实现(四)之uni-app离线插件

目的 在前三篇文章中完成了银行卡识别整个模型训练等工作&#xff0c;通过了解PaddleOCR的端侧部署&#xff0c;我们也可以将银行卡号检测模型和识别模型移植到手机中&#xff0c;做成一款uni-app手机端离线银行卡号识别的应用。 准备工作 为了不占用过多篇幅&#xff0c;这…