ZK集群出现网络波动导致一部分provider无法重新注册

问题产生场景:
    Ephermal节点未及时删除导致provider不能恢复注册,在应用日志中,应用重连Zookeeper成功后,provider立刻进行了重新注册,之后便没有打印任何日志。而在ZK日志中,注册节点被删除后,并没有重新创建注册节点。
 

public void register(URL url) {
		super.register(url);
		failedRegistered.remove(url);
		failedUnregistered.remove(url);
		try{
			doRegister(url);
		} catch (Exception e) {
			Throwable t = e;
			boolean check = t instanceof SkipFailbackWrapperException;
			if(check || skipFailback) {
				if(skipFailback) {
					t = t.getCause();
				}
				throw new IllegalStateException("Failed to register " + url + "to registry " + getUrl().getAddress() + ", cause: " + t.getMessage(),t);
			} else {
				logger.error("Failed to register " + url + ", waiting for retry, cause: " + t.getMessage(), t);
			}
			failedRegistered.add(url);
		}
	}

Dubbo默认使用curator作为Zookeeper的客户端,curator与ZK是通过session未知链接的。当curator重连ZK时,若session未过期,则继续使用原session重新链接。而Ephemeral节点与session是绑定的关系,在session过期后,会删除此session下的Ephemeral节点。
    继续对doRegister(url)的代码进行进一步排查,发现在CuratorZookeeperClient.createEphemeral(path)方法中有这么一段逻辑:在createEphemeral(path)捕获到了NodeExistsException,创建Ephemeral节点时,若此节点已存在,则认为Ephemeral创建成功。
    但当ZK的session过期与删除Ephemeral节点不是原子性的操作情况下。在客户端得到session过期的消息时,session对应的Ephemeral节点可能还未被ZK删除。此时Dubbo去创建Ephemeral节点,发现节点仍然存在,所以不再创建新节点。当Ephemeral节点被ZK删除后,便会出现Dubbo认为重新注册成功但实际未成功的情况,会导致一部分的provider无法重新注册到ZK上。

public void createEphemeral(String path) {
		try {
			client.create().withMode(CreateMode.EPHEMERAL).forPath(path);
		} catch (NodeExistsException e) {
		} catch (Exception e) {
			throw new IllegalStateException(e.getMessage(), e);
		}
	}


解决方案:
    1.临时方案:手动重启provider。
    2.升级Dubbo版本至2.7.3(需要检测此版本是否与线上环境兼容,目前此版本不与DubboX兼容)
    3.修改源码,当Ephemeral节点捕获到NodeExistsException时,进行判断,若Ephemeral节点的SessionId与当前客户端的SessionId不同,则删除并重建Ephemeral节点。

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值