某日中午,午睡正香的时候,接到系统的报警电话,提示生产某物理机异常宕机了,目前该物理机已恢复,需要重启上面部署的应用。

这时瞬间没有了睡意,登上堡垒机,快速重启了应用,系统恢复正常。本想着继续午睡,但是已经没有了睡意。

旁边的小师弟(我们叫他小灰吧)刚才在我们边上,目睹这一切,然后向我请教个问题。

小灰:

黑哥,刚才应用突然宕机,会不会对交易有影响啊?

小黑:

影响确实会有,不过也不大,就当时应用正在运行那些那些交易会受到影响。

小灰:

不对啊,我们现在系统架构是下面这样。

我们这次宕机的是业务逻辑层,那按照目前使用 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 服务治理中心下发配置。这时 routersconfigurators 就会增加相关配置。

小灰:

嘿嘿,咱接下来讲服务注册流程。

当服务提供者启动之后,会向注册中心写入自己的元数据信息,其实就是在 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 帮你自动搞定服务隔离!的更多相关文章

  1. Kafka服务不可用(宕机)问题踩坑记

    背景 某线上日志收集服务报警,打开域名报502错误码. 收集服务由2台netty HA服务器组成,netty服务器将客户端投递来的protobuf日志解析并发送到kafka,打开其中一个应用的日志,发 ...

  2. windows服务,安装、启动、停止,配置,一个批处理文件搞定

    相对而言,还是比较通用的吧,如果哪位仁兄有更好的实现方式,或者发现有不足之处,还请多多指教.  @echo off echo.------------------------------------- ...

  3. 线上服务宕机,码农试用期被毕业,原因竟是给MySQL加个字段

    1. 问题:怎么给线上表加字段? 工作中最常遇到的问题,怎么给线上频繁使用的大表添加字段? 比如:给下面的用户表(user)添加年龄(age)字段. CREATE TABLE `user` ( `id ...

  4. keepalived+nginx实现niginx高可用,宕机自动重启

    nginx作为http服务器,在集群中 用于接受客户单发送过来的请求,并且根据配置的策略将请求 转发给具体的哪台服务器 如果在nginx服务器使用轮询策略处理客户端的请求,出现了tomcat 宕机的情 ...

  5. 由Redis的hGetAll函数所引发的一次服务宕机事件

    昨晚通宵生产压测,终于算是将生产服务宕机的原因定位到了,心累.这篇博客,算作一个复盘和记录吧... 先来看看Redis的缓存淘汰算法思维导图: 说明:当实际占用的内存超过Redis配置的maxmemo ...

  6. 【JVM】linux上tomcat中部署的web服务,时好时坏,莫名其妙宕机,报错:There is insufficient memory for the Java Runtime Environment to continue.

    =========================================================================================== 环境: linu ...

  7. java服务宕机原因查询

    背景 在java服务项目上线之后经常会出现宕机的情况 常见原因 内存溢出 1.查到服务进程号 [root@wms ~]# ps -ef|grep java root 6399 6069 0 08:57 ...

  8. Hadoop 服务SYS CPU过高导致宕机问题

    最近某hadoop集群多次出现机器宕机,现象为瞬间机器的sys cpu增长至100%,机器无法登录.只能硬件重启,ganglia cpu信息如下: 首先怀疑有用户启动了比较奇葩的job,导致不合理的系 ...

  9. 记-ItextPDF+freemaker 生成PDF文件---导致服务宕机

    摘要:已经上线的项目,出现服务挂掉的情况. 介绍:该服务是专门做打印的,业务需求是生成PDF文件进行页面预览,主要是使用ItextPDF+freemaker技术生成一系列PDF文件,其中生成流程有:解 ...

随机推荐

  1. PHP addcslashes() 函数

    实例 在字符 "W" 前添加反斜杠: <?php 高佣联盟 www.cgewang.com$str = addcslashes("Hello World!" ...

  2. 5.5 省选模拟赛 B Permutation 构造 贪心

    LINK:Permutation 对于这种构造神题 我自然是要补的.为啥就我没想出来哇. 30分还是很好写的 注意8!实际上很小 不需要爆搜 写bfs记录状态即可.至于判断状态是否出现与否 可以开ma ...

  3. python flask构建小程序订餐系统--centos下项目开发环境的搭建

    1.项目开发环境的搭建(Linux环境) 1)软件的安装 我们搭建整个项目的过程中,我们需要用到下面的一些软件,但是这些软件的安装过程我们在这里不用说明.(因为windows软件的安装比较的简单,类似 ...

  4. “随手记”开发记录day07

    今天完成了关于我们页面中的相关信息,由于之前没有做过这个东西,只想着用一个view解决 可是发现我们整的太简单了,还是太年轻,最后想出来要跟java代码一起解决这个问题, 效果

  5. 手把手教你使用Python网络爬虫获取招聘信息

    1.前言 现在在疫情阶段,想找一份不错的工作变得更为困难,很多人会选择去网上看招聘信息.可是招聘信息有一些是错综复杂的.而且不能把全部的信息全部罗列出来,以外卖的58招聘网站来看,资料整理的不清晰. ...

  6. mogilefs 安装与配置

    安装步骤 配置yum 的epel源 yum install perl-Sys-Syslog perl-IO-AIO perl-Net-Netmask -y # 安装依赖的包 取得mogilefs的rp ...

  7. 《Spanner: Google’s Globally-Distributed Database》论文总结

    Spanner 总结 说明:本文为论文 <Spanner: Google's Globally-Distributed Database> 的个人理解,难免有理解不到位之处,欢迎交流与指正 ...

  8. JDBC的开发步骤

    一.JDBC概述 JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问, 它由一组用Jav ...

  9. Jdk1.8下的HashMap源码分析

    目录结构 一.面试常见问题 二.基本常量属性 三.构造方法 四.节点结构        4.1 Node类        4.2.TreeNode 五.put方法        5.1 key的has ...

  10. LeetCode746 Min Cost Climbing Stairs(爬上楼梯的最小损失)

    题目 On a staircase, the i-th step has some non-negative cost cost[i] assigned (0 indexed). Once you p ...