dubbo+zookeeper模拟宕机后问题复现及解决办法

为什么要模拟?

主要原因有两个,第一个是想验证下网上说的那些理论,毕竟别人说的跟自己去做理解起来可能不一样。第二个是确实测试环境下出现问题,两台服务器,服务器A上部署了所有服务加一个zk,服务器B上部署了mysql加2个zk。
有次服务器B宕机了,然后整个服务全都断了。一开始以为是mysql断了,所以只要服务器重启起来,zk重启,应该服务都好了。后来发现就算服务器起来了,mysql能连上,服务还是挂了,所有接口都访问不了,只有将所有服务重新启动,重新注入到zk中才行。所以想模拟下找到原因,看看为什么服务都需要重启遍才行。过程比较繁琐,如果不想看过程,可以直接翻到最后看结果。

1.单机模拟

直接启动zk,启动dubbo,zk使用单机模式的。
dubbo+zookeeper模拟宕机后问题复现及解决办法_第1张图片
dubbo 也启起来,由于服务还没起,所以列表中是空的
dubbo+zookeeper模拟宕机后问题复现及解决办法_第2张图片
下面将服务启起来,服务都是打包好的jar,直接运行起来。服务如下,2个提供者,2个消费者,端口号分别为881,882,981,982,dubbo端口分别为20881,20882,20981,20982
在这里插入图片描述
先起一个提供者和消费者(881和981),看看效果,可以看到dubbo admin 中显示了提供者的信息了,我们请求下接口看看。
dubbo+zookeeper模拟宕机后问题复现及解决办法_第3张图片
接口能正常返回数据
dubbo+zookeeper模拟宕机后问题复现及解决办法_第4张图片
现在将zk关掉,看看还能不能访问。
dubbo+zookeeper模拟宕机后问题复现及解决办法_第5张图片
可以看到zk断掉以后,dubbo admin 直接就看不到服务了。我们再看看接口还能正常访问吗?
dubbo+zookeeper模拟宕机后问题复现及解决办法_第6张图片
可以看到接口仍然是可以正常访问的,看看控制台中,提供者和消费者正在不断的尝试重连zk。
dubbo+zookeeper模拟宕机后问题复现及解决办法_第7张图片
既然现有接口访问都是正常的,我们看看能不能在启动另一个提供者,向zk中发布服务。
dubbo+zookeeper模拟宕机后问题复现及解决办法_第8张图片
可以看到 demo-providers-1.0-SNAPSHOT_882_20882.jar 我们的第二个服务是无法启动的,现在再把zk启起来,我们看看这个服务能否启动?
dubbo+zookeeper模拟宕机后问题复现及解决办法_第9张图片
dubbo+zookeeper模拟宕机后问题复现及解决办法_第10张图片
可以看到 ,当我们把zk启起来后,2个提供者都显示在上面了而且请求接口也可以切换提供者。

单机模拟总结

  • 当注册中心(zk)挂掉后,之前的服务提供者和消费者都能正常使用,接口能正常访问,是通过本地缓存继续获取服务列表的
  • 当注册中心挂掉后,服务提供者和消费者会不断重连zk,直到注册中心再次启动
  • 当注册中心挂掉后,新的服务不能发布,必须等注册中心起来后,才能发布

2.集群模拟

这里就直接上集群了,zk怎么部署集群,可以网上查查,或者看看我其它文章。为了模拟测试环境,本机起一个zk,虚拟机上起2个zk。
dubbo+zookeeper模拟宕机后问题复现及解决办法_第11张图片
zk集群起来后,通过命令查看下状态可以发现,本机和132虚拟机上的2182为follower,132上的2182为leader。
dubbo+zookeeper模拟宕机后问题复现及解决办法_第12张图片
下面启动服务,本机上启动一个提供者(881),一个消费者(981),虚拟机上启动一个提供者(882) 开始在集群上测试。
dubbo+zookeeper模拟宕机后问题复现及解决办法_第13张图片
dubbo+zookeeper模拟宕机后问题复现及解决办法_第14张图片
ok,现在dubbo admin上和接口看都是正常,现在开始模拟异常情况,先我们将虚拟机的ip地址换下。
在这里插入图片描述
将132换成133后,看看有什么情况,这种情况相当于2个zk和一个提供者(882)宕机了。
dubbo+zookeeper模拟宕机后问题复现及解决办法_第15张图片
通过命令可以看到,zk是挂了,连接不上了,dubbo admin 重启后也看不到服务了,那我们猜想现在接口还通吗?
dubbo+zookeeper模拟宕机后问题复现及解决办法_第16张图片
发现接口始终还是可以了,但是提供者始终是881了,虚拟机上的882没有出现。这里发现一个有趣的现象,一开始访问接口时,有时候很快有时候很慢,快的都返回是881,估计
慢的都是在调用882上的提供者,不过是超时了。过了一段时间后就一直很快了,不会出现慢的,说明应该是把882踢出服务列表了。
dubbo+zookeeper模拟宕机后问题复现及解决办法_第17张图片
现在我们再把ip改回来,看看效果。等待几分钟后看到zk自动重连了,leader变成132上的2183了。
dubbo+zookeeper模拟宕机后问题复现及解决办法_第18张图片
但是dubbo admin无法看到服务,
dubbo+zookeeper模拟宕机后问题复现及解决办法_第19张图片
再看看接口,发现接口无法请求,报异常了,无法找到服务提供者。
在这里插入图片描述
dubbo+zookeeper模拟宕机后问题复现及解决办法_第20张图片
尝试重启下消费者,看看能不能重新获取到提供者?发现消费者无法启动,说明提供者不在zk中了。
dubbo+zookeeper模拟宕机后问题复现及解决办法_第21张图片
现在将2个提供者和一个消费者都重启下,看看效果。
dubbo+zookeeper模拟宕机后问题复现及解决办法_第22张图片
dubbo+zookeeper模拟宕机后问题复现及解决办法_第23张图片
dubbo+zookeeper模拟宕机后问题复现及解决办法_第24张图片
都正常了,这个跟测试环境遇到的问题很像,服务器断了之后,无法发布,就算服务器起来,zk启起来,也无法正常调用接口,必须重启服务,重新发布才行,
下面我们在试下,这次是直接将虚拟机关机重启,不是切换ip了,看看是不是跟换ip一样的问题。
dubbo+zookeeper模拟宕机后问题复现及解决办法_第25张图片
相同的,zk挂了,然后接口正常,dubbo admin 如果不重启是直接拿的缓存的数据,显示还是正常的,如果重启下admin就会没了。
dubbo+zookeeper模拟宕机后问题复现及解决办法_第26张图片
现在把虚拟机启起来,再把zk也启起来,看看能不能自动重连上。
dubbo+zookeeper模拟宕机后问题复现及解决办法_第27张图片
通过命令可以看到,zk自动连上了,但是跟切换ip一样的问题,接口挂了,服务提供者找不到,dubbo admin也找不到服务。这也就证明了跟测试环境一样,
一旦集群超过半数宕机后,就算机器立马起来,集群虽然可以自动重连,但是服务都断了,需要重新运行下才行。

集群模拟总结

  • 当zk集群超过半数宕机后,之前的服务都能正常使用,通过缓存取的服务信息
  • 当zk集群超过半数宕机后,新的服务无法发布到集群中
  • 当集群重新启动后,zk可以自动重连,但是消费者会在一段时间后报错,无法找到提供者,必须重启提供者才行,消费者不需要重启。

问题总结

后面将单机的也测试一遍,发现跟集群一样,也是重启zk后,提供者找不到了,必须重启提供者才行。
那么根据结论我们可以看出是提供者没了,才造成接口请求失败的,那我们直接观察zk中的提供者状态就行了。
通过实验可以发现(下图),在正常运行的时候我们的提供者节点上是有数据的。当zk宕机重启后,zk的提供者节点数据没了。所以才造成接口请求失败,提示找不到提供者了。
在这里插入图片描述
在这里插入图片描述

那么为什么节点数据会丢那?通过继续深入的研究(这里就不说了),发现原因是我们提供者的节点是临时节点,而/dubbo,/dubbo/providers 这些是持久化节点。临时节点跟我们的
zk session相关,当session丢失或者超时,那么这个临时节点也就没了。
在这里插入图片描述
下图是,超时时间过了,session被关闭的日志,这里超时时间为40秒。为啥是40秒,可以查询zk的minSessionTimeout和maxSessionTimeout,超时时间范围为 2tickTime < 超时时间 <20tickTime
在这里插入图片描述
正常情况下,如果我们是网络问题,或者秒起zk也是没有问题的。因为超时时间未到,zk重启后能继续使用session。所以,后面单机zk或者集群宕机了,如果没有及时去启动,那么需要去看下节点信息。如果节点中数据没有了,需要重启下提供者才行。

你可能感兴趣的:(Java)