Dubbo的设计理念原来就藏在这三张图中
Dubbo在众多的微服务框架中脱颖而出,占据RPC服务框架的半壁江山,非常具有普适性,熟练掌握 Dubbo的应用技巧后深刻理解其内部实现原理,让大家能更好的掌控工作,助力职场,特别能让大家在面试中脱颖而出。
那Dubbo内部的设计理念,实现原理是什么呢?
本文将结合官方提供的3张图,从如下三个方面介绍其内部的核心实现、以及如何指导实践。
1、服务注册与发现机制
Dubbo的服务注册与发现机制如下图所示:
在Dubbo中存在4类角色:
- Registry
注册中心。 - Consumer
服务调用者、消费端。 - Provider
服务提供者。 - Monitor
监控中心。
具体的交互流程包括如下关键步骤:
- 服务提供者在启动的时候向注册中心进行注册。
- 消息消费者在启动的时候向注册中心订阅指定服务,注册中心将以某种机制(推或拉)模式告知消费端服务提供者列表。
- 当服务提供者数量变化(服务提供者扩容、缩容、宕机等因素),注册中心需要以某种方式(推或拉)告知消费端,以便消费端进行正常的负载均衡。
- 服务提供者、服务消费者向监控中心汇报TPS等调用数据,以便监控中心进行可视化展示等。
Dubbo官方提供了多种注册中心,接下来将以使用最为普遍的Zookeeper进一步介绍注册中心的原理。
首先我们来看一下Zookeeper注册中心中的数据存储目录结构,从目录结构来窥探其实现机制。
Dubbo Zookeeper注册中心,其目录组织结构为 /dubbo/{ServiceName},再每一个服务名称下会有4个目录:
- providers
服务提供者列表。 - consumers
消费者列表 - routers
路由规则列表,关于一个服务可以设置多个路由规则。 - configurators
动态配置条目。在Dubbo中可以在不重启消费者、服务提供者的前提下动态修改服务提供者、服务消费者的配置,例如修改线程的数量,超时时间等参数。
基于Zookeeper注册中心的实现细节如下:
- 服务提供者启动时会向注册中心注册,主要是在对应服务的providers目录下增加一条记录(临时节点),同时监听 configurators节点。
- 服务消费者启动时会向注册中心订阅,主要是在对应服务的consumers目录下增加一条记录(临时节点),同时监听 configurators、routers 目录。
- 由于当有新的服务提供者上线后 providers 目录会增加一条记录,消费者能立马收到一个服务提供者列表变化的通知,得以将最新的服务提供者列表推送给服务调用方(消费端);如果一个服务提供者宕机,由于创建的节点是临时节点,Zookeeper会将该节点移除,同样会触发事件,消费端得知最新的服务提供者列表,从而实现路由的动态注册与发现。
- 当Dubbo新版本上线后,如果需要进行灰度发布,可以通过dubbo-admin等管理平台添加路由规则,最终会写入到指定服务的router节点(持久节点),服务调用方会监听该节点的变化,从而感知最新的路由规则,将其用于服务提供者的筛选,从而实现灰度发布等功能。
- 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线程中不能有阻塞操作,阻塞操作需要转发到业务线程池。
好了,本文就介绍到这里了,您的点赞与转发是对我持续输出高质量文章最大的鼓励。
欢迎关注公众号『中间件兴趣圈』,共同探究源码,交流高并发、架构经验,回复 PDF 更是可获取大量学习资料。
Dubbo的设计理念原来就藏在这三张图中的更多相关文章
- 隱藏在素數規律中的Pi -- BZOJ1041解題報告
退役狗在刷程書的過程中看到了一個有趣的視頻, 講解了一個有趣的問題. 在網上隨便搜索了一下居然還真的找到了一道以它爲背景的OI題目, BZOJ1041. 下面的內容會首先回顧一下視頻所討論的知識, 有 ...
- 一张图比較 Docker 和 Git:镜像管理设计理念
Docker 的镜像管理设计中大量借鉴了 Git 的理念. 以下这张图将对两者的核心概念和操作进行比較,有助于大家高速掌握管理 Docker 镜像的正确方式. watermark/2/text/aHR ...
- STL算法设计理念 - 二元函数,二元谓词以及在set中的应用
demo 二元函数对象 #include <iostream> #include <cstdio> #include <vector> #include <a ...
- 使用dubbo引用和发布服务时出现的异常:HTTP状态500 - 请求处理失败; 嵌套异常是com.alibaba.dubbo.rpc.RpcException:无法在服务cn.e3mall.service.ItemService中调用方法getTbItemById。使用dubbo版本2.5.3在消费者...
异常情况如下: 从异常看,主要是因为TbItem没有序列化: 分析问题: 表现层调用服务端时返回了一个TbItem对象即Java对象,此时这个对象远程调用拿过来必须进行序列化,要进行网络传输必须先要把 ...
- CPU 执行程序的秘密,藏在了这 15 张图里
前言 代码写了那么多,你知道 a = 1 + 2 这条代码是怎么被 CPU 执行的吗? 软件用了那么多,你知道软件的 32 位和 64 位之间的区别吗?再来 32 位的操作系统可以运行在 64 位的电 ...
- dubbo分布式rpc框架用法
dubbo是阿里巴巴开源的分布式服务框架,致力于提供高性能和透明化的rpc远程服务调用方案,以及soa服务治理方案,如果没有分布式需求,是不需要dubbo的,分布式环境dubbo的使用架构官方给出了一 ...
- Dubbo原理解析-监控
Dubbo发布代码中,自带了一个简易的监控中心实现.对于一般的小业务这个监控中心应该能够满足需求,对于那些大业务量的大公司一般都会有自己的监控中心,更加丰富的功能如常用的报警短信通知等等.这章讲解分析 ...
- Dubbo.xml配置源-Dubbo.xsd分析
我们使用Dubbo时,一般都会使用xml配置基本信息,如项目名称(application).注册中心(register).协议(protocal).服务(service),如下所示: 1 2 3 ...
- 微服务架构-选择Spring Cloud,放弃Dubbo
Spring Cloud 在国内中小型公司能用起来吗?从 2016 年初一直到现在,我们在这条路上已经走了一年多. 在使用 Spring Cloud 之前,我们对微服务实践是没有太多的体会和经验的.从 ...
随机推荐
- 面试 07-安全问题:CSRF和XSS
07-安全问题:CSRF和XSS #前言 面试中的安全问题,明确来说,就两个方面: CSRF:基本概念.攻击方式.防御措施 XSS:基本概念.攻击方式.防御措施 这两个问题,一般不会问太难. 有人问: ...
- 初始Node
node是什么? 一句话: 服务器 什么是服务器: 一句话: 客户端访问 并且能够响应 为什么: 一句话: 执行效率高 #安装 #控制台 切换磁盘: e: 改变目录: cd 目录 cd.. ...
- QEMU网络模式(一)——bridge
网络配置 QEMU支持的网络模式 qemu-kvm主要向客户机提供了4种不同模式的网络. 1)基于网桥(bridge)的虚拟网卡; 2)基于NAT的虚拟网络 3)QEMU内置的用户模式网络(user ...
- 利用设计模式消除业务代码中的 if-else
准备工作:假设这样的一个业务场景:有一个自动开票的功能需要实现,在程序里面需要根据账单的类型执行对应的处理逻辑. 以下使用了 Lombok 简化代码!!! 账单类型枚举: /** * @author ...
- Java基础-方法的重写和重载
重载(Overload)和重写(Override) 重载是在同一个类里面,方法名字相同,而参数不同.返回类型可以相同也可以不同.每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表. 重写 ...
- win10开启运行下显示历史操作记录
步骤 设置,隐私,常规,允许windows跟踪应用启动,以改进开始和搜索结果
- EF快速入门--直接修改(简要介绍ObjectContext处理机制)
原博文 http://www.cnblogs.com/fly_dragon/archive/2011/06/05/2073084.html ObjectContext的处理机制 ObjectConte ...
- 【Windows系统常用命令集合】
查看建立的TCP连接:netstat -n 查看建立的TCP连接的进程:netstat -nb 查看本机侦听的端口: netstat -an (说明:如果端口没有侦听 检查服务) 测试到远程计算机的某 ...
- Error:(12, 24) 警告: [deprecation] android.hardware中的Camera已过时.android
问题:android studio编译项目时出现: Error:(12, 24) 警告: [deprecation] android.hardware中的Camera已过时 解决:(只是让其不提示) ...
- jfinal项目报java.lang.ClassNotFoundException: com.jfinal.core.JFinalFilter
在eclipse中启动jfinal项目时,项目报错如下:首先:右击项目–>Build Path–>Source查看Default output folder如果是目录/WEB-INF/cl ...