服务应用突然宕机了?别怕,Dubbo 帮你自动搞定服务隔离!
某日中午,午睡正香的时候,接到系统的报警电话,提示生产某物理机异常宕机了,目前该物理机已恢复,需要重启上面部署的应用。
这时瞬间没有了睡意,登上堡垒机,快速重启了应用,系统恢复正常。本想着继续午睡,但是已经没有了睡意。
旁边的小师弟(我们叫他小灰吧)刚才在我们边上,目睹这一切,然后向我请教个问题。
小灰:
黑哥,刚才应用突然宕机,会不会对交易有影响啊?
小黑:
影响确实会有,不过也不大,就当时应用正在运行那些那些交易会受到影响。
小灰:
不对啊,我们现在系统架构是下面这样。

我们这次宕机的是业务逻辑层,那按照目前使用 Dubbo 轮询的负载均衡方式,不是还会有交易分发到宕机那台应用上,这些交易请求显然会异常。
运气差点,不是会有一半交易请求都会有问题吗?
小黑:
没错,我们的系统架构图确实如说的一样。
不过你说的这个问题,它是不存在的。
这是因为 Dubbo 内部会自动帮我们的摘除宕机的应用节点。
小灰:
啥?Dubbo 内部还有这功能啊?黑哥你给我讲讲原理呗!
小黑:
可以啊,不过讲这个原理之前,我们首先需要了解 Dubbo 服务注册发现流程。
我看你最近一直在看『深入理解 Apache Dubbo 与实战』,这本书确实不错,里面框架原理,代码细节都讲的很透彻。
你应该已经了解了 Dubbo 服务注册发现流程,那你先跟我简单讲讲原理吧。
小灰拿起纸笔,在上面画了个图:

恩,我当前了解的还不是很深,那我先聊聊目前我知道的。
我们目前使用 ZooKeeper 当做服务注册中心,ZooKeeper 可以简单理解成是一个 KV系统,内部是一个树形的数据结构。
Dubbo 默认将会在 ZooKeeper 中创建一个四层的数据结构,从上到下分别为:
- Root
- Service
- Category
- URL
其中 Root 层是注册中心分组,默认命名为 dubbo。我们可以通过修改 <dubbo:registry> 中的 group 属性修改默认值,这样修改之后不同分组的 dubbo 服务不会互相影响,也不会互相调用,可以用于环境隔离。
接下来 Service 就是服务类的全路径,包括包路径。
Service 层下面就是 Category 层,这其中总共有四类目录(上面图形只画了两种),分别为:
- providers:包含服务提供者 URL 元数据信息
- consumers:包含消费者 URL 元数据信息
- routers:包含消费者路由策略的 URL 元数据信息
- configurators:包含动态配置元数据信息
最后一层就是具体 Dubbo 服务 URL,类似如下:
dubbo://2.0.1.13:12345/com.dubbo.example.DemoService?xx=xx
小黑:
没错,这个内部结构你理还是蛮清晰的么!
平常使用的情况下,我们重点关注 providers 以及 consumers 就好了。如果我们需要配置服务路由信息以及动态配置,那我们需要在 Dubbo-Admin 服务治理中心下发配置。这时 routers 与 configurators 就会增加相关配置。
小灰:
嘿嘿,咱接下来讲服务注册流程。
当服务提供者启动之后,会向注册中心写入自己的元数据信息,其实就是在 providers 节点下创建一个 URL 节点(如果上级节点都不存在,将会逐层创建),存储值类似如下:
dubbo://10.10.11.22:20880/com.foo/BarService?key=value....
接着启动服务消费者,消费者第一次连接上 ZooKeeper 时,将会拉取provider 节点下所有服务提供者的 URL 信息,然后与相应的服务提供者建立连接。
同时服务消费者也会将自己信息注册到在 consumer 节点下,这个目的是为了服务治理中心(Dubbo-Admin)发现自己。
同时消费者将会在 provider 节点上注册一个 watcher ,当有新的服务提供者启动成功,provider 节点发生变更,ZooKeeper 将会推送变更信息给 Dubbo 服务,然后 Dubbo 将会重新建立与服务提供者的连接。
小黑:
你说的整个 Dubbo 服务注册发现流程没有什么问题,这里消费者与服务提供者建立的连接的流程,我们之前踩过一个坑,你有空可以看看 天啦噜!生产机器连接数飙升到上万,背后发生了什么?。
另外,再考你一下:
服务节点变更时,ZooKeeper 推送 provider 下全量子节点数据给消费者吗?
小灰:
呀,难道不是吗?
小黑:
不是的。ZooKeeper 的 watch 机制目前只能推送节点变更信息,比如节点内容数据变更,监听节点下子节点列表变更等,具体如下图:

进一步从 Zookeeper 客户端的源码上来看,watcher 回调通知内容最终转为 WatchedEvent。

这个类只有三个字段,所以是不会推送子节点列表数据过来。
小灰:
既然不是通过推送获取子节点列表的信息,那如何拿到变动子节点列表?
有了,在收到推送的时候,我们能获取到变动节点信息,然后我再拉取一下子节点的列表不就好了!
小黑:
没错,Dubbo 就是这么做的。
这一点我们可以具体看下 Dubbo 的源码,位于 CuratorZookeeperClient。
画外音:下面的源码基于 Dubbo 2.6.7

图中标注的地方,Dubbo 通过拉取获取了字节点的全量数据,同时再次注册了一个 watcher 。
不过这么多,有个缺陷的,当微服务节点数量有很多的时候,全量拉取将会占用过多的内网带宽,很容易造成网络风暴。
上面我们讲到 Zookeeper 的这种方式,是一种典型的 Push 模式,对应的还有一种的模式为 Pull 模式,eureka 就是这种模式的典型的代表。
eureka 客户端就是通过定期轮询拉取数据,获取最新的变更数据。不过拉取模式也存在很大的劣势,如果轮询频率低,那么服务变更信息无法及时获取,如果轮率太高这就会增加注册中心的压力。
小黑:
服务发现流程这下我们已经搞明白了。如果有新增服务节点,Dubbo 消费者通过通知,然后再拉取全量的子节点列表,这样 Dubbo消费者就会新增与新的服务提供者连接,后续再通过负载均衡使用新的连接。
如果 Dubbo 服务提供者正常停止下线,那么他将会删除 ZooKeeper 上的自己注册的节点信息。删除之后 Dubbo 消费者第一时间收到了通知,通过拉取全量的子节点列表,然后通过比对,发现某个节点下线,然后删除之前简历的连接。这样后续,就不会再调用这个节点。
小灰:
恩,正常应用上下线,Dubbo 消费者可以感知到,但是像服务提供者宕机的情况,消费者是怎么感知到的?
小黑:
这一点,就与 Zookeeper 的自身特性有关了。
Zookeeper 中我们可以创建四种节点类型的节点:
- 永久节点
- 临时节点
- 顺序节点
- 永久节点
- 临时节点
临时节点与永久节点唯一的区别在于,一旦 Zookeeper 客户端断开连接,Zookeeper 服务感知到之后就会自动删除临时节点。
Dubbo 服务提供者就是在 Zookeeper 注册了临时节点,如果服务提供者宕机了,临时节点自动被删除,后面的流程就跟 Dubbo 应用正常下线一样了。
小灰:
すごい!原来如此,这个设计 666 啊。
小黑:
其实应用宕机这种, Dubbo RPC 框架内部都可以自动帮我们处理,这种故障其实很好处理。但是如果碰到下面这这种情况:
- 服务提供者与服务消费者网络隔离
- 服务提供陷入缓慢
在服务消费者看来,服务提供者其实是「活着」,这是因为服务提供者与 Zookeeper 还是正常连接。
但是实际情况下,服务消费者其实已经不能正常调用服务提供者了,那这种情况就比较棘手了。
不过 Dubbo 内部也提供了解决办法。马上就上班了,也来不及讲了,我们后面再讨论!
小灰:
好的,黑哥!今天学到了!
黑哥
服务应用突然宕机了?别怕,Dubbo 帮你自动搞定服务隔离!的更多相关文章
- Kafka服务不可用(宕机)问题踩坑记
背景 某线上日志收集服务报警,打开域名报502错误码. 收集服务由2台netty HA服务器组成,netty服务器将客户端投递来的protobuf日志解析并发送到kafka,打开其中一个应用的日志,发 ...
- windows服务,安装、启动、停止,配置,一个批处理文件搞定
相对而言,还是比较通用的吧,如果哪位仁兄有更好的实现方式,或者发现有不足之处,还请多多指教. @echo off echo.------------------------------------- ...
- 线上服务宕机,码农试用期被毕业,原因竟是给MySQL加个字段
1. 问题:怎么给线上表加字段? 工作中最常遇到的问题,怎么给线上频繁使用的大表添加字段? 比如:给下面的用户表(user)添加年龄(age)字段. CREATE TABLE `user` ( `id ...
- keepalived+nginx实现niginx高可用,宕机自动重启
nginx作为http服务器,在集群中 用于接受客户单发送过来的请求,并且根据配置的策略将请求 转发给具体的哪台服务器 如果在nginx服务器使用轮询策略处理客户端的请求,出现了tomcat 宕机的情 ...
- 由Redis的hGetAll函数所引发的一次服务宕机事件
昨晚通宵生产压测,终于算是将生产服务宕机的原因定位到了,心累.这篇博客,算作一个复盘和记录吧... 先来看看Redis的缓存淘汰算法思维导图: 说明:当实际占用的内存超过Redis配置的maxmemo ...
- 【JVM】linux上tomcat中部署的web服务,时好时坏,莫名其妙宕机,报错:There is insufficient memory for the Java Runtime Environment to continue.
=========================================================================================== 环境: linu ...
- java服务宕机原因查询
背景 在java服务项目上线之后经常会出现宕机的情况 常见原因 内存溢出 1.查到服务进程号 [root@wms ~]# ps -ef|grep java root 6399 6069 0 08:57 ...
- Hadoop 服务SYS CPU过高导致宕机问题
最近某hadoop集群多次出现机器宕机,现象为瞬间机器的sys cpu增长至100%,机器无法登录.只能硬件重启,ganglia cpu信息如下: 首先怀疑有用户启动了比较奇葩的job,导致不合理的系 ...
- 记-ItextPDF+freemaker 生成PDF文件---导致服务宕机
摘要:已经上线的项目,出现服务挂掉的情况. 介绍:该服务是专门做打印的,业务需求是生成PDF文件进行页面预览,主要是使用ItextPDF+freemaker技术生成一系列PDF文件,其中生成流程有:解 ...
随机推荐
- 初学用记事本运行java报错:找不到或无法加载主类解决方法,部分出错解决办法
刚开始学习java的人第一个程序可能通过记事本运行,当中间可能会会出现各种错误,我在下面间可能解决出现的问题 1. java环境变量没有安装好 以我的win10系统为例,在装好相应的jdk后,环境变量 ...
- Codeforces Round #649 (Div. 2) E. X-OR 交互 二进制 随机 期望
LINK:X-OR 本来是应该昨天晚上发的 可是昨天晚上 做这道题 写了一个分治做法 一直wa 然后查错 查不出来 心态崩了 想写对拍 发现交互库自己写不出来. 一系列sb操作 == 我都醉了. 今天 ...
- luogu P4525 自适应辛普森法1
LINK:自适应辛普森法1 观察题目 这个东西 凭借我们的数学知识应该是化简不了的. 可以直接认为是一个函数 求定积分直接使用辛普森就行辣. 一种写法: double a,b,c,d; double ...
- CF习题集二
CF习题集二 一.CF507E Breaking Good 题目描述 \(Breaking Good\)这个游戏对于有经验的玩家来说也有一定的难度. 游戏的主角小明希望加入一个叫斧头帮的犯罪团伙.这个 ...
- 实用!一键生成数据库文档,堪称数据库界的Swagger
本文收录在个人博客:www.chengxy-nds.top,技术资料共享,同进步 最近部门订单业务调整,收拢其他业务线的下单入口,做个统一大订单平台.需要梳理各业务线的数据表,但每个业务线库都有近百张 ...
- 基于开源串口调试助手修改的qcom
代码已上传码云: https://gitee.com/fensnote/qcom.git 源代码用于串口编程的学习很有价值,谢谢Qter的开源项目,感谢花心萝卜工作室的修改版本. 开源的qt开发的串口 ...
- 在IntelliJ IDEA中多线程并发代码的调试方法
通常来说,多线程的并发及条件断点的debug是很难完成的,或许本篇文章会给你提供一个友好的调试方法.让你在多线程开发过程中的调试更加的有的放矢. 我们将通过一个例子来学习.在这里,我编写了一个多线程程 ...
- 1、迭代器 Iterator模式 一个一个遍历 行为型设计模式
1.Iterator模式 迭代器(iterator)有时又称游标(cursor)是程序设计的软件设计模式,可在容器(container,例如链表或者阵列)上遍访的接口,设计人员无需关心容器的内容. I ...
- 2020-07-05:tcp和udp的区别和应用场景。如何实现断点续传?
福哥答案2020-07-05: 区别:1.可靠性:tcp可靠.udp不可靠.2.连接性:tcp面向连接.udp无连接.3.报文:tcp字节流.udp面向报文.4.传输效率:tcp低.udp高.5.多点 ...
- clients-producer-网络处理与请求响应对接部分