zookeeper重启,线上微服务全部掉线,怎么回事?

这篇具有很好参考价值的文章主要介绍了zookeeper重启,线上微服务全部掉线,怎么回事?。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

注册中心zookeeper被重启,线上微服务全部掉线,怎么回事?!

最近因为一次错误的运维操作,导致线上注册中心zk被重启。而zk重启后发现所有线上微服务开始不断掉线,造成了持续30分钟的P0故障。

整体排查过程深入学习了 zookeeper的session机制,以及在这种异常情况下,RPC框架应该如何处理。

好了,一起来回顾下这次线上故障吧,最佳实践总结放在最后,千万不要错过。

1、现象描述

某天晚上19:43分左右,误操作将线上zk集群下线(stop),总共7台节点,下线了6台,导致zk停止工作。

在发现节点下掉后,于19:51分左右将所有zk节点进行重启(start),期间服务正常运行,没有收到批量业务调用的报错和客诉。

直到19:56分,开始收到大面积调用失败的警报和客诉,我们尝试着依赖自研RPC框架与zk间重连后的「自动恢复」机制,希望能够在短时间内批量恢复。

但是很不幸,过了接近8分钟,没有任何大面积恢复的迹象。结合zk znode节点数上升非常缓慢的情况,于是我们采取了应急措施,将所有微服务的pod原地重启,执行重启后效果显著,大面积服务在短时间内逐步恢复。

2、初步分析

我们自研的RPC框架采用典型的 注册中心+provider+consumer 的模式,通过zk临时节点的方式做服务的注册发现,如下图所示。

zookeeper重启,线上微服务全部掉线,怎么回事?

 文章来源地址https://www.toymoban.com/news/detail-412103.html

结合故障期间发生的现象,我们初步分析:

  • 阶段1:zk集群停服(stop)期间,业务能够正常调用。原因是consumer无法访问zk,暂时失去服务发现能力,所以在这个期间只要服务没有重启,就不会刷新本地的服务发现provider缓存列表provider-list,调用无异常。
  • 阶段2:zk集群启动完毕后,服务间立刻出现调用问题。原因是consumer连接上zk后,立刻进行服务发现操作,然而provider服务这时还没重新注册到zk,读取到的是空地址列表,造成了业务的批量报错。
  • 阶段3:zk恢复后续一段时间,provider服务仍然没「自动重连」到zk,导致consumer持续报错。在所有服务全量重启后,provider服务重新注册成功,consumer恢复。

这里存在一个问题:

  • 为什么zk集群恢复后,provider客户端「自动重连」注册中心的机制没有生效?导致consumer被推送了空地址列表后,没有再收到重新的provider注册节点信息了。

3、深入排查

3.1 问题复现

根据大量测试和真实表现,我们找到了稳定复现本次问题的方法:

zk session过期包括 「服务端过期」 和 「客户端过期」,在「客户端过期」情况下恢复zk集群,会导致「临时节点」丢失,且无法自动恢复的情况。

3.2 分析

1)在集群重启恢复后,RPC框架客户端立刻就与zk集群取得重连,将保存在本地内存待注册的providers节点 + 待订阅的consumers节点 进行重建。

2)但是zk集群此时根据snapshot恢复的「临时节点」(包括provider和consumer) 都还在,因此重建操作返回NodeExist异常,重建失败了。(问题1:为什么没有重试?)

3)在集群重启恢复40s后,将过期Session相关的 临时节点全都移除了。(问题2:为什么要移除?)

4)consumer监听到 节点移除 的空列表,清空了本地provider列表。故障发生了。

基于这个分析,我们需要进一步围绕2个问题进行源码的定位:

  • 问题1:zk集群恢复后,前40s,为什么RPC框架的客户端在创建临时节点失败后没有重试?
  • 问题2:zk集群恢复后,40s后,为什么zk会删除之前所有已经恢复的临时节点?

3.3 问题1:为什么临时节点创建失败没有重试?

通过源码分析,我们看到,RPC框架客户端与服务端取得重连后,会将内存里老的临时节点进行重新创建。

这段逻辑看来没有什么问题,doRegister成功之后才会将该节点从失败列表中移除,否则将继续定时去重试创建。

zookeeper重启,线上微服务全部掉线,怎么回事?

 

继续往下走,关键点来了:

zookeeper重启,线上微服务全部掉线,怎么回事?

 

这里我们可以看到,在创建临时节点时,吞掉了服务端返回的NodeExistsException,使整个外层的doRegister和doSubscribe(订阅)方法在这种情况下都被认为是重新创建成功,所以只创建了一次。

正如上面分析的,其实正常情况下,这里对NodeExistsException不做处理是没有问题的,就是节点已经存在不用再添加了,也不需要再重试了,但是伴随服务端后续踢出老sessionId同时删除了相关临时节点,就引起了故障。

3.4 问题2:zk为什么删除已经恢复的临时节点

3.4.1 从zk的session机制说起

众所周知,zk session管理在客户端、服务端都有实现,并且两者通过心跳进行交互。

在发送心跳包时,客户端会携带自己的sessionId,服务端收到请求,检查sessionId确认存活后再发送返回结果给客户端。

如果客户端发送了一个服务端并不知道的sessionId,那么服务端会生成一个新的sessionId颁布给客户端,客户端收到后本地进行sessionid的刷新。

3.4.2 zk客户端(curator)session过期机制

当客户端(curator)本地sessionTimeout超时时,会进行本地zk对象的重建(reset),我们从源码可以看到默认将本地的sessionId重置为0了。

zookeeper重启,线上微服务全部掉线,怎么回事?

 

zookeeper重启,线上微服务全部掉线,怎么回事?

 

zk服务端后续收到这个为“0”sessionId,认为是一个未知的session需要创建,接着就为客户端创建了一个新的sessionId。

3.4.3 服务端(zookeeper)session过期处理机制

服务端(zookeeper) sessionTimeout的管理,是在zk会话管理器中看到一个线程任务,不断判断管理的session是否有超时(获取下一个过期时间点nextExpirationTime已经超时的会话),并进行会话的清理。

zookeeper重启,线上微服务全部掉线,怎么回事?

 

我们继续往下走,关键点来了,在清理session的过程中,除了将sessionId从本地expiryMap中清除外,还进行了临时节点的清理:

zookeeper重启,线上微服务全部掉线,怎么回事?

 

原来zkserver端是将sessionId和它所创建的临时节点进行了绑定。伴随着服务端sessionId的过期,绑定的所有临时节点也会随之删除。

因此,zk集群恢复后40s,zk服务端session超时,删除了过期session的所有相关临时节点。

4、 故障根本原因总结

1)zk集群恢复的第一时间,对zk的snapshot文件进行了读取并初始化zk数据,取到了老session,进行了create session的操作,完成了一次老session的续约(重置40s)。

集群恢复关键入口-重新加载snapshot:

zookeeper重启,线上微服务全部掉线,怎么回事?

 

反序列化最近的snapshot文件,并读取session恢复到本地内存:

zookeeper重启,线上微服务全部掉线,怎么回事?

 

进行session恢复(创建)操作,默认session timeout 40s:

zookeeper重启,线上微服务全部掉线,怎么回事?

 

2)而此时客户端session早已经过期,带着空sessionid 0x0进行重连,获得新sessionId。但是此时RPC框架在临时节点注册失败后吞掉了服务端返回的NodeExistsException,被认为是重新创建成功,所以只创建了一次。

3)zk集群恢复后经过40s最终因为服务端session过期,将过期sessionId和及其绑定的临时节点进行了清除。

4)consumer监听到 节点移除 的空列表,清空了本地provider列表。故障发生了。

5、解决方案

经过上面的源码分析和解答,解决方案有两种:

方案1:客户端(curator)设置session过期时间更长或者不过期,那么集群恢复后的前40s,客户端带着原本的sessionid跟服务端做一次请求,就自动续约了,不再过期。

方案2:客户端session过期后,带着空sessionid 0x0进行重连的时候,对NodeExsitException做处理,进行 删除-重添加 操作,保证重连成功。

于是我们调研了一下业界使用zk的开源微服务框架是否支持自愈,以及如何实现的:

dubbo采用了方案2。

zookeeper重启,线上微服务全部掉线,怎么回事?

 

注释也写的非常清楚:

“ZNode路径已经存在,因为我们只会在会话过期时尝试重新创建节点,所以这种重复可能是由zk服务器的删除延迟引起的,这意味着旧的过期会话可能仍然保存着这个ZNode,而服务器只是没有时间进行删除。在这种情况下,我们可以尝试删除并再次创建。”

看来dubbo确实后续也考虑到这个边界场景,防止踩坑。

所以最后我们的解决方案也是借鉴dubbo fix的逻辑,进行节点的替换:先deletePath再createPath,这么做的原因是将zk服务端内存维护的过期sessionId替换新的sessionId,避免后续zk清理老sessionId时将所有绑定的节点删除。

6、最佳实践

回顾整个故障,我们其实还忽略了一点最佳实践。

除了优化对异常的捕获处理外,RPC框架对注册中心的空地址推送也应该做特殊判断,用业界的专业名词来说,就是「推空保护」。

所谓「推空保护」,就是在服务发现监听获取空节点列表时,维持本地服务发现列表缓存,而不是清空处理。

这样可以完全避免类似问题。

 

都看到最后了,原创不易,点个关注,点个赞吧~
文章持续更新,可以微信搜索「阿丸笔记 」第一时间阅读,回复【笔记】获取Canal、MySQL、HBase、JAVA实战笔记,回复【资料】获取一线大厂面试资料。
知识碎片重新梳理,构建Java知识图谱:github.com/saigu/JavaK…(历史文章查阅非常方便)

到了这里,关于zookeeper重启,线上微服务全部掉线,怎么回事?的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 服务器有网络连接但无法上网是怎么回事

    服务器有网络连接但无法上网是怎么回事 一、网络设置的问题 这种原因比较多出现在需要手动指定IP、网关、DNS服务器联网方式下,及使用代理服务器上网的。仔细检查计算机的网络设置。 二、DNS服务器的问题 当IE无法浏览网页时,可先尝试用IP地址来访问,如果可以访问,

    2024年02月11日
    浏览(51)
  • 宽带上网经常掉线重启后正常过会又掉线的处理方法

    故障现象: 宽带上网经常掉线,有时重启电脑正常。使用一段时间又出现掉线现象。 解决方案: 1. 首先核实是否有多台电脑同时上网,或是当前电脑有没有在进行P2P下载或在线视频之类比较占用网络带宽的操作,此操作可能导致宽带数据量过大影响稳定性。若存在此情况,请

    2024年02月06日
    浏览(154)
  • 路由器掉线需要不断重启解决方案

      正常上网一段时间后,网吧路由器就莫名其妙的掉线了,关闭路由器,稍等一会儿再开启网络又正常了。路由器掉线需要不断重启该怎么办?下面小编为您提供解决方法。 造成网吧路由器不断掉线的问题有多种,需要通过排除法来进行一一排查。 1.首先,需要检查路由器的

    2024年02月05日
    浏览(43)
  • 幻兽帕鲁服务器连接异常、闪退、掉线以及进不去游戏等问题,怎么解决?

    幻兽帕鲁服务器连接异常、闪退、掉线以及进不去游戏等问题的解决方法包括: 检查网络连接 :确保网络连接正常,可以尝试优化网络环境或使用网络加速器来提高连接速度和稳定性。 检查服务器状态 :通过游戏官方网站或社交媒体页面了解服务器状态,以判断是否因为服

    2024年03月11日
    浏览(58)
  • 重启tomcat-Tomcat服务器怎么重启?

    Tomcat服务器重启的办法: 第一步:使用cmd进入dos界面 第二步:进入Tomcat安装目录 C:UsersAdministrator.MS-E: E:cdapache-tomcat–windows-apache-tomcat-i E:apache-tomcat–windows-apache-tomcat-in 到bin目录之后,先关闭原来运行的Tomcat服务器 第三步:关闭方法:执行shutdown.bat指令 E:apache-tomcat–windows

    2024年02月04日
    浏览(41)
  • 线上Zookeeper问题解决记录

    zookeeper问题: 日志目录:  /home/cmccdata/app/zookeeper/logs dataDir=/home/cmccdata/app/zookeeper/data/zoodata dataLogDir=/home/cmccdata/app/zookeeper/data/zoolog 问题0:    解决方案:     关闭防火墙 问题1: 解决方案: 删除/home/cmccdata/app/zookeeper/data/zoodata/version-2/ 下 currentepoch文件 问题2: 解决方案: 删除/home/

    2024年02月14日
    浏览(35)
  • 网吧路由器怎么设置才能不掉线避免电脑掉线现象

    网吧电脑掉线现象,一直都是困扰网吧业主和网吧管理员的心病。为了避免出现掉线,各大网络设备生产商也在网吧路由器花尽了心思,今天小编就和你分享,网吧路由器怎么设置才能不掉线: 内部PC限制NAT的链接数量 NAT功能是在网吧中应用最广的功能,由于IP地址不足的原因

    2024年02月06日
    浏览(47)
  • 夏天无线路由器总是掉线该怎么办?让无线路由器不在掉线的技巧

    大夏天的,天太热了我的路由终于支持不住了,老是掉线。下面的方法也试用于个位动手能强的朋友哦。亲们可以来试试呀很好玩的用着也很稳定。 1、我们来先把电源适配器该拆了外壳就不要用了,太大占地方不说也是涉及到散热不好。 2、我们来把我们的无线路由器也拆了

    2024年02月08日
    浏览(45)
  • zookeeper动态扩缩容(无需重启)

    目录 一、启动一个zk 二、扩容一个zk 三、缩容一个zk 四、重新配置集群的节点 前言: zookeeper动态扩/缩容的reconfig命令旨在不需要重启zookeeper中任何一个节点的情况下,对整个zookeeper集群进行动态扩/缩容。 zookeeper客户端支持的命令: 在实际验证中发现一些细节问题,先记录

    2024年02月21日
    浏览(45)
  • 怎么解决无线网间歇性掉线问题

    问题分析 很多用户反馈这个问题,期初我们也认为就是驱动的问题,随着研究的深入发现这也很可能是由于无线网卡和路由器之间的PSPM模式不兼容产生的。 PSPM(Power Save Polling Mode)是一种用于延长笔记本电脑电池使用时间的无线网络节能技术。这种技术要求无线路由器和笔

    2024年02月07日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包