问题概述
使用客户端连接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:created