zookeeper session

Session什么时候创建

在ZooKeeper中,客户端和服务端建立连接后会创建一个session(会话),每一个session对应一个全局唯一的会话ID(Session ID)。就像浏览器和Web服务器一样,首次连接Web服务器的时候为了跟踪客户端,Web服务器会创建一个Session。

Session超时

zookeeper服务器和客户端之间维持的是一个长连接,客户端会定时向服务器发送心跳来维持Session的有效性(每次发送心跳就会刷新session超时时间)。正常情况下Session一直有效,并且ZK集群所有机器上都保存这个Session信息。当出现网络中断或zookeeper服务挂掉时,客户端会主动在地址列表(实例化ZK对象的时候传入构造方法的那个参数connectString)中选择新的地址进行连接(如果没有备选地址,会不断重试之前的那个地址),如果有新的地址可以连接,在中断时长小于sessionTimeout值时,zookeeper客户端自动重连。如果中断时长大于sessionTimeout值时,将出现session expired的异常,这个时候就需要开发者手动做一些处理,比如使用zookeeper的create重建连接。

如何监听Session超时事件

在创建zookeeper对象时,指定的Watcher是zookeeper客户端默认的Watcher,可以在它的process方法中监听到Session超时事件,具体做法:

/**
	 * 当type=None(-1)时,有四种情况:
	 * 	1. zookeeper已连接
	 * 	2. 会话超时!
	 * 	3. zookeeper连接已关闭
	 * 	4. zookeeper认证失败
	 * @param watchedEvent zookeeper event
	 */
	@Override
	public void process(WatchedEvent watchedEvent) {
		Event.EventType type = watchedEvent.getType();
		Event.KeeperState state = watchedEvent.getState();
		int stateValue = state.getIntValue();
		logger.info("监听到变化,type=" + type.getIntValue() + ",name=" + type.name());
		logger.info("state=" + state.getIntValue() + ",name=" + state.name());
		if (type.getIntValue() == Event.EventType.None.getIntValue()) {
			if (stateValue == Event.KeeperState.SyncConnected.getIntValue()) {
				logger.info("zookeeper已连接!");
				countDownLatch.countDown();
			}else if (stateValue == Watcher.Event.KeeperState.Expired.getIntValue()) {
				logger.info("zookeeper会话超时!");
				//zookeeper连接是异步的,所以用CountDownLatch保证zookeeper连接成功后再通知Listeners
				countDownLatch = new CountDownLatch(1);
				ZooKeeper zooKeeper = createNewZookeeper();
				try {
					countDownLatch.await();
				}
				catch (InterruptedException e) {
					e.printStackTrace();
				}
				noticeListener(zooKeeper);
			}else if (stateValue == Watcher.Event.KeeperState.Closed.getIntValue()) {
				logger.info("zookeeper连接已关闭!");
			}else if (stateValue == Watcher.Event.KeeperState.AuthFailed.getIntValue()) {
				logger.info("zookeeper认证失败!");
			}
		}

Seession超时后如何重建连接,需要注意什么

重新new 一个zookeeper即可,使用zookeeper提供的API,如下:

public ZooKeeper(String connectString, int sessionTimeout, Watcher watcher) throws IOException{
        this(connectString, sessionTimeout, watcher, false);
}

但是需要注意session超时之后,之前使用Java API注册的Watcher将丢失,比如:

public void addWatch(String basePath, AddWatchMode mode)
            throws KeeperException, InterruptedException {
        addWatch(basePath, watchManager.defaultWatcher, mode);
}

所以在重建连接之后,你需要重新添加监听。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值