前言
dubbo是一个成熟且被广泛运用的框架。饶是如此,在某些极端条件下基于dubbo的应用还会出现无法重连zookeeper的问题。由于此问题容易导致比较大的故障,所以笔者费了一番功夫去定位,现将排查过程写成博文分享出来。
Bug现场
这是一起在测试环境出现的故障。起因是网工做交换机切换演练,可能由于姿势不对,使得断网的时间从预估的秒级达到了分钟级。等网络恢复后,测试环境就炸开了锅,基本上所有应用再也无法提供服务,在dubbo控制台上也看不到任何提供者,他们和zk的连接都断开而且似乎完全没有重连的迹象。如下图所示:
无法快速恢复
为了不影响测试的进度,运维同学紧急进行了重启,但坑爹的是大部分系统都有启动依赖,盲目的重启只会因为xxx provider不存在而无法启动。只能从最基础的服务开始重启,慢慢恢复。如下图所示:
还好只是测试环境,但为了不让产线出现这种问题,必须一查到底,把这个Bug揪出来。
着手排查
模拟zookeeper连接断开
测试环境的好处是我们可以用各种手段去模拟复现,而不用和处理产线一样到处寻找蛛丝马迹然后进行逻辑推理(推理是一个非常烧脑的过程)。于是笔者联系了SA同学,通过iptables进行线下的断网模拟。命令如下所示:
// 禁用本机和zk三台机器的流量进出
iptables -A INPUT -s zk-1-ip/32 -j DROP
iptables -A INPUT -s zk-2-ip/32 -j DROP
iptables -A INPUT -s zk-3-ip/32 -j DROP
iptables -A OUTPUT -s zk-1-ip/32 -j DROP
iptables -A OUTPUT -s zk-2-ip/32 -j DROP
iptables -A OUTPUT -s zk-3-ip/32 -j DROP
拓扑图如下:

发现在drop对zk的包之后,不管等待多长时间,只要连接一放开,立马就能重连zk! 看来dubbo对zookeeper的重连还是非常靠谱的。
同时模拟DNS断开
由于模拟zk断开不会导致无法重连的现象。于是笔者开始思考,是否交换机异常的时候导致了所有的包都无法发送/接收,而导致重连出问题的并不是对zookeeper发起连接。于是笔者看了看配置,是否还有其它和重连有关联的点,仔细观察下这个配置:
// 这其中有一个不容易注意到的点,就是域名解析也需要网络包的交互
dubbo.registry.address=zookeeper://dubbo-1.com?back=dubbo-2.com,dubbo-3.com
难道是DNS访问不到导致了这一问题?反正测试环境,继续模拟一发,命令如下所示:
// 禁用本机和zk三台机器的流量进出
iptables -A INPUT -s zk-1-ip/32 -j DROP
iptables -A INPUT -s zk-2-ip/32 -j DROP
iptables -A INPUT -s zk-3-ip/32 -j DROP
iptables -A OUTPUT -s zk-1-ip/32 -j DROP
iptables -A OUTPUT -s zk-2-ip/32 -j DROP
iptables -A OUTPUT -s zk-3-ip/32 -j DROP
// 禁用本机和DNS两台机器的流量进出
iptables -A INPUT -s dns-ip/32 -j DROP
iptables -A INPUT -s dns-ip/32 -j DROP
iptables -A OUTPUT -s dns-ip/32 -j DROP
iptables -A OUTPUT -s dns-ip/32 -j DROP
网络拓扑如下:

这次我们在禁用流量后,故意先放开对zk的流量,再放开对DNS的流量,如下图所示:

本文记录了一次在测试环境中,由于网络异常导致Dubbo应用无法重连Zookeeper的问题。通过模拟网络断开和DNS故障,发现当DNS无法响应时, Dubbo的重连机制会失效。经过查阅资料和代码分析,确认了是低版本Zookeeper客户端的bug,升级到3.4.13或更高版本后问题得到解决。提醒开发者对于测试环境的问题也要重视,防止类似问题发生在生产环境。
2006

被折叠的 条评论
为什么被折叠?



