Dubbo的设计理念原来就藏在这三张图中,读完恍然大悟了

Dubbo在众多的微服务框架中脱颖而出,占据RPC服务框架的半壁江山,非常具有普适性,熟练掌握 Dubbo的应用技巧后深刻理解其内部实现原理,让大家能更好地掌控工作,助力职场,特别能让大家在面试中脱颖而出。

那Dubbo内部的设计理念,实现原理是什么呢?

本文将结合官方提供的3张图,从如下三个方面介绍其内部的核心实现、以及如何指导实践。

1、服务注册与发现机制

Dubbo的服务注册与发现机制如下图所示:

在Dubbo中存在4类角色:

  • Registry注册中心。* Consumer服务调用者、消费端。* Provider服务提供者。* Monitor监控中心。

具体的交互流程包括如下关键步骤:

  1. 服务提供者在启动的时候向注册中心进行注册。
  2. 消息消费者在启动的时候向注册中心订阅指定服务,注册中心将以某种机制(推或拉)模式告知消费端服务提供者列表。
  3. 当服务提供者数量变化(服务提供者扩容、缩容、宕机等因素),注册中心需要以某种方式(推或拉)告知消费端,以便消费端进行正常的负载均衡。
  4. 服务提供者、服务消费者向监控中心汇报TPS等调用数据,以便监控中心进行可视化展示等。

Dubbo官方提供了多种注册中心,接下来将以使用最为普遍的Zookeeper进一步介绍注册中心的原理。

首先我们来看一下Zookeeper注册中心中的数据存储目录结构,从目录结构来窥探其实现机制。

Dubbo Zookeeper注册中心,其目录组织结构为 /dubbo/{ServiceName},在每一个服务名称下会有4个目录:

  • providers服务提供者列表。* consumers消费者列表* routers路由规则列表,关于一个服务可以设置多个路由规则。* configurators动态配置条目。在Dubbo中可以在不重启消费者、服务提供者的前提下动态修改服务提供者、服务消费者的配置,例如修改线程的数量,超时时间等参数。

基于Zookeeper注册中心的实现细节如下:

  1. 服务提供者启动时会向注册中心注册,主要是在对应服务的providers目录下增加一条记录( 临时节点 ),同时监听 configurators节点。
  2. 服务消费者启动时会向注册中心订阅,主要是在对应服务的consumers目录下增加一条记录( 临时节点 ),同时监听 configurators、routers 目录。
  3. 由于当有新的服务提供者上线后 providers 目录会增加一条记录,消费者能立马收到一个服务提供者列表变化的通知,得以将最新的服务提供者列表推送给服务调用方(消费端);如果一个服务提供者宕机,由于创建的节点是临时节点,Zookeeper会将该节点移除,同样会触发事件,消费端得知最新的服务提供者列表,从而实现路由的动态注册与发现。
  4. 当Dubbo新版本上线后,如果需要进行灰度发布,可以通过dubbo-admin等管理平台添加路由规则,最终会写入到指定服务的router节点(持久节点),服务调用方会监听该节点的变化,从而感知最新的路由规则,将其用于服务提供者的筛选,从而实现灰度发布等功能。
  5. configurators 节点的运作机制与 router 节点一样,就不重复介绍。

扩展思考:

1、如果注册中心全部宕机,对整个服务体系会有什么影响?

如果整个注册中心全部宕机,整个 服务调用 能正常工作,不会影响现有的服务消费者调用,但消费端无法发现新注册的服务提供者。

2、如果注册中心内存溢出或频繁发生 Full Gc,对整个集群又会带来什么影响呢?

如果频繁发生Full GC,并且如果Full GC的时间超过了Zookeeper会话的过期时间,将会造成 非常严重的影响 ,会触发所有临时节点被删除,消费端将无法感知服务提供者的存在,影响服务调用,将大面积抛出 No provider 等错误。 正所谓成也临时节点、败也临时节点

为了避免Full Gc带来的严重后果,用于Dubbo注册中心的Zookeeper,一定会要独享,并及时做好内存、CPU等的监控与告警。

2、服务调用

Dubbo的服务调用设计十分优雅,其实现原理如下图所示:

服务调用,重点阐述客户端发起一个RPC服务调用时的所有实现细节,包括服务发现故障转移路由转发负载均衡等方面,是Dubbo实现灰度发布的理论基础。

2.1 服务发现

客户端在向服务端发起请求时,首先需要知道的是当前有哪些可用的服务提供者,通常有两种服务发现机制:

  • 静态化配置不妨回想一下,在Dubbo等微服务框架出现之前,一个模块调用另外一个模块通常的做法是使用一个配置文件,将服务提供的列表配置配置在配置文件中,客户端从按照配置文件中的列表进行轮循。其 弊端 也非常明显:如果需要调用的服务众多,配置文件会变得臃肿,对扩容缩容的管理、机器宕机等变更不友好,管理非常困难。* 动态发现通常基于注册中心实现服务的注册与动态发现,由于上文已详细介绍,在这里就不赘述。

2.2 负载均衡

客户端通过服务发现机制,能动态发现当前存活的服务提供者列表,接下来要考虑的是如果从服务提供者列表中选择一个服务提供者发起调用,这就是所谓的 负载均衡 ,即 LoadBalance。

在Dubbo中默认提供了随机、加权随机、最少活跃连接、一致性Hash等负载均衡算法。

2.3 路由机制

其实Dubbo中不仅提供了负载均衡机制,还提供了智能路由机制,这是实现 Dubbo灰度发布 的理论基础。

所谓的路由机制,是在服务提供者列表中,再设置一定的规则,进行过滤选择,负载均衡时只从路由过滤规则筛选出来的服务提供者列表中选择,为了更加形象的阐述路由机制的工作原理,给出如下示意图:


上述设置了一条路由规则,即查询机构ID为102的查询用户请求信息,请发送到新版本,即192168.3.102上,那主要在进行负载均衡之前先执行路由规则,从原始的服务提供者列表者按照路由规则进行过滤,从中挑选出符合要求的提供者列表,然后再进行负载均衡。

路由机制的核心理念:在进行 负载均衡之前 先对 服务提供者列表 运用 路由规则 ,得出一个参与负载均衡的提供者列表。

2.4 故障转移

远程服务调用通常涉及到网络等因素,客户端向服务提供者发起RPC请求调用时并不一定100%成功,当调用失败后该采用何种策略呢?

Dubbo提供了如下策略:

  • failover失败后选择另外一台服务提供者进行重试,重试次数可配置,通常适合 实现幂等服务的场景。* failfast快速失败,失败后立即返回错误。* failsafe调用失败后打印错误日志,返回成功,通常 用于记录审计日志等场景 。* failback调用失败后,返回成功,但会在后台定时无限次重试,重启后不再重试。* forking并发调用,收到第一个响应结果后返回给客户端。通常适合 实时性要求比较高的场景 ,但浪费服务器资源,通常可以通过forks参数设置并发调用度。

3、线程派发机制

Dubbo的通信线程模型如下图所示:

3.1 网络通信协议

网络传输通常需要自定义通信协议,通常采用 Header + Body 的协议设计理念 ,并且 Header 长度固定,并且包含一个长度字段,用于记录整个协议包的大小。

网络传输为了提高传输效率,可以采取对传输数据进行压缩,通常是对 body 进行序列化与压缩。

Dubbo支持目前支持 java、compactedjava、nativejava、fastjson、fst、hessian2、kryo等序列化协议。

3.2 线程派发机制

在Dubbo中默认会创建200个线程用于处理业务方法,所谓的线程派发机制就是IO线程如何决定何种请求转发到哪类线程中执行。

目前Dubbo中 所有的心跳包、网络读写在IO线程中执行 ,无法通过配置进行修改。

Dubbo提供了如下几种线程派发机制(Dispatcher):

  • all所有的请求转发到业务线程池中执行(除IO读写、心跳包)* message只有请求事件在线程池中执行,其他在IO线程上执行。* connection请求事件在线程池中执行, 连接、断开连接事件排队执行(含一个线程的线程池) 。* direct所有请求直接在IO线程中执行。

温馨提示:有关线程模型,网络通信模式,可以参考笔者如下这篇文章。

线程派发机制之所有会有多种策略,主要是考虑 线程切换 带来的开销是否能容忍,即线程切换带来的开销小于多线程处理带来的提升。

例如在Dubbo中,对心跳包只需直接返回PONG包(OK),逻辑非常简单,如果将其转换到业务线程池,并不能带来性能提升,反而因为需要线程切换,带来性能损耗,故在IO线程中直接发送响应包是一个非常可取的做法。

在网络编程中需要遵循一条 最佳实践 : IO线程中不能有阻塞操作,阻塞操作需要转发到业务线程池 。

本文就介绍到这里了,希望可以对大家学习Dubbo的知识有帮助,喜欢的小伙伴可以帮忙转发+关注,感谢大家!

原文链接:
https://www.tuicool.com/articles/7zMbAfA

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,837评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,551评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,417评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,448评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,524评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,554评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,569评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,316评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,766评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,077评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,240评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,912评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,560评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,176评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,425评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,114评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,114评论 2 352

推荐阅读更多精彩内容

  • 一、从单体到微服务架构演变 1.1单体架构 所有的应用程序都部署在一个单体的项目上。 优点 小项目开发快 成本低 ...
    HelloWorld打断点阅读 556评论 0 0
  • Dubbo 核心组件 层次作用Service该层与业务逻辑相关,根据 provider 和 consumer 的业...
    Q南南南Q阅读 523评论 0 0
  • 一、Dubbo是什么 Dubbo 是一个分布式、高性能、透明化的 RPC 服务框架,提供服务自动注册、自动发现等高...
    小波同学阅读 2,513评论 0 10
  • Apache Dubbo是一款高性能的 Java RPC 框架。其前身是阿里巴巴公司开源的一个高性能、轻量级的开源...
    acc8226阅读 506评论 0 1
  • 目录 1 应用架构演变 2 RPC 3 Dubbo概述 4 Dubbo配置 5 Dubbo协议 6 高...
    小小千千阅读 561评论 0 0