ZooKeeper过期续订的实现

问题概述

使用客户端连接ZooKeeper过程中有时会因为网络延时的原因跟ZooKeeper集群断开连接。一旦断开的时间超过了配置文件中规定的时间,ZooKeeper集群就会设置sessionId过期,并清空该客户端产生的临时数据。而即使后来该客户端又重新连接到了ZooKeeper集群,ZooKeeper集群会发送一个Expired事件通知客户端会话已经过期。

问题的解决

要重新连接到ZooKeeper集群,只需要重新new一个ZooKeeper对象,重新产生一个会话即可。但是需要注意,由于这个会话是一个全新的会话,过期会话产生的临时信息也不会被恢复了。因此如果需要保持一些临时信息在ZooKeeper集群中不丢失,我们的代码要妥善的处理这个问题。

在我之前的Mrpc框架中,ServerRegister类需要保持注册的服务器地址信息,让其保存在ZooKeeper集群中。由于我创建的是临时节点,一旦会话过期,ZooKeeper会将这些信息全部删除。因此必须监听会话的状态,一旦收到会话过期通知,就要重新连接ZooKeeper集群,并在连接成功后依次检查已创建的信息项目,如果有项目不存在就再次重新创建。

重点代码

// 处理zk事件
public void process(WatchedEvent event) {
    System.out.println("register:------" + event);
    if(event.getState() == Event.KeeperState.SyncConnected){
        latch.countDown();
        try {
            // 逐个查找之前创建过的临时节点,不存在的重新创建
            Map<String,String> newTempNodes = new HashMap<String,String>();
            for(Map.Entry<String, String> entry:createdTempNodes.entrySet()){
                Stat stat = zk.exists(entry.getKey(), null);
                if(stat == null){
                    // 重新创建
                    String newNode = zk.create(entry.getKey(), entry.getValue().getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
                    newTempNodes.put(newNode, entry.getValue());
                }else{
                    // 还存在,不需要重新创建
                    newTempNodes.put(entry.getKey(), entry.getValue());
                }
            }
            createdTempNodes = newTempNodes;
        } catch (Exception e) {

        }
    }
    if(event.getState() == Event.KeeperState.Expired){
        try {
            // 会话过期,重新连接ZooKeeper集群
            initZk();           

        } catch (Exception e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
    }

}

private void initZk() throws Exception {
    latch = new CountDownLatch(1);
    this.zk = new ZooKeeper(zkConnetionString, sessionTimeout, this);
    latch.await(sessionTimeout + 100, TimeUnit.MILLISECONDS);
    if(latch.getCount() > 0){
        throw new RuntimeException("Can not connect to ZooKeeper cluster " 
                + zkConnetionString + ", please check and try again later");
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值