本文介绍在使用curator框架的时候如何handle session expire。

1、什么是zookeeper的会话过期?

一般来说,我们使用zookeeper是集群形式,如下图,client和zookeeper集群(3个实例)建立一个会话session。

在这个会话session当中,client其实是随机与其中一个zk provider建立的链接,并且互发心跳heartbeat。zk集群负责管理这个session,并且在所有的provider上维护这个session的信息,包括这个session中定义的临时数据和监视点watcher。

如果再网络不佳或者zk集群中某一台provider挂掉的情况下,有可能出现connection loss的情况,例如client和zk provider1连接断开,这时候client不需要任何的操作(zookeeper api已经给我们做好了),只需要等待client与其他provider重新连接即可。这个过程可能导致两个结果:

1)在session timeout之内连接成功

这个时候client成功切换到连接另一个provider例如是provider2,由于zk在所有的provider上同步了session相关的数据,此时可以认为无缝迁移了。

2)在session timeout之内没有重新连接

这就是session expire的情况,这时候zookeeper集群会任务会话已经结束,并清除和这个session有关的所有数据,包括临时节点和注册的监视点Watcher。

在session超时之后,如果client重新连接上了zookeeper集群,很不幸,zookeeper会发出session expired异常,且不会重建session,也就是不会重建临时数据和watcher。

2、如何使用curator实现session expired异常的捕获和处理?

1)首先我们先创建一个链接

这里设置了重试策略retryPolicy和会话超时时间sessionTimeoutMs,并打开链接。

public void init() {
RetryPolicy retryPolicy = new ExponentialBackoffRetry(baseSleepTimeMs, maxRetries);
client = CuratorFrameworkFactory.builder().connectString(zookeeperServer).retryPolicy(retryPolicy)
.sessionTimeoutMs(sessionTimeoutMs).connectionTimeoutMs(connectionTimeoutMs).build();
client.start();
}

2)客户端注册

public void register() {
try {
String rootPath = "/services";
String hostAddress = InetAddress.getLocalHost().getHostAddress();
String serviceInstance = "/prometheus" + "-" + hostAddress + "-";
String path = rootPath + serviceInstance;
SessionConnectionListener sessionConnectionListener = new SessionConnectionListener(path, "");
client.getConnectionStateListenable().addListener(sessionConnectionListener);
client.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL_SEQUENTIAL).forPath(path);
} catch (Exception e) {
logger.error("注册出错", e);
}
}

这里我们创建了一个临时有序节点node,这个节点将会在session expired触发的时候被自动删除。当session又重新恢复的时候,client只会收到session expired异常和不会自动将临时节点添加到zookeeper中。

为了解决这个问题,我们增加了一个监听器,

client.getConnectionStateListenable().addListener(sessionConnectionListener)

这个监听器监听session expired事件,并且在事件发生的时候进行处理,监听器处理的流程如下。

注意:这个监听器注册是可以复用的,即如果多次session expired,不用重复注册监听器。

3、监听器sessionConnectionListener

package com.xiaoju.dqa.prometheus.client.zookeeper;

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.state.ConnectionState;
import org.apache.curator.framework.state.ConnectionStateListener;
import org.apache.zookeeper.CreateMode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; public class SessionConnectionListener implements ConnectionStateListener {
private final Logger logger = LoggerFactory.getLogger(this.getClass()); private String path;
private String data; public SessionConnectionListener(String path, String data) {
this.path = path;
this.data = data;
} @Override
public void stateChanged(CuratorFramework curatorFramework, ConnectionState connectionState){
if(connectionState == ConnectionState.LOST){
logger.error("[负载均衡失败]zk session超时");
while(true){
try {
if(curatorFramework.getZookeeperClient().blockUntilConnectedOrTimedOut()){
curatorFramework.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL_SEQUENTIAL).forPath(path, data.getBytes("UTF-8"));
logger.info("[负载均衡修复]重连zk成功");
break;
}
} catch (InterruptedException e) {
break;
} catch (Exception e){ }
}
}
}
}

这里的ConnectionState.LOST等同于session expired事件,对这个事件的处理是,在一个死循环中重试链接zk,知道链接成功才退出循环。

需要注意的是:一旦重新创建了会话,那么之前会话的所有观察点都会失效,需要重新初始化观察点。

zookeeper curator处理会话过期session expired的更多相关文章

  1. Session过期,跳出iframe框架页显示会话过期页面

    web开发中经常会有这种情况,在一个主页面中包含侧边导航菜单和iframe,点击菜单项,对应页面会在iframe中显示,整个页面不会刷新.但是如果设置了会话Session,在会话过期后再操作会自动re ...

  2. zookeeper设置客户端连接超时被expired

    在网络环境非常差的情况下,使用zookeeper集群往往会遇到连接expired了: 客户端提示连接从ZOO_CONNECTION_STATE变为ZOO_EXPIRED_SEESION_STATE,然 ...

  3. php中会话保持 session 与cooker

    会话保持 1.session Session:在计算机中,尤其是在网络应用中,称为"会话控制".Session 对象存储特定用户会话所需的属性及配置信息.这样,当用户在应用程序的 ...

  4. ASP.NET会话(Session)保存模式--终于知道session为什么丢失了

    [原创]ASP.NET会话(Session)保存模式 作者:寒羽枫(cityhunter172) 大家好,已有四个多月没写东东啦.今日抽空就说一下 Session 在 .Net v1.0/v1.1 中 ...

  5. 会话控制:SESSION,COOKIE

    1.http协议: HTTP—超文本传输协议,在TCP协议(长连接.像一个硬件)基础上; 特点:短连接,无状态协议,没法记录本次连接的状态;适用于静态页面的访问,对于后期某些页面是需要浏览器预知客户信 ...

  6. [JS] Ajax请求会话过期处理

    对于页面来说,处理session过期比较简单,一般只需在过滤器里面判断session用户是否存在,不存在则跳转页面到登陆页即可. 对于Ajax请求来说,这个办法则无效,只能获取到登录页的html代码. ...

  7. Ajax请求会话过期处理(JS)

    对于页面来说,处理session过期比较简单,一般只需在过滤器里面判断session用户是否存在,不存在则跳转页面到登陆页即可. 对于Ajax请求来说,这个办法则无效,只能获取到登录页的html代码. ...

  8. 会话追踪(session tracking)

    HTTP是一种无连接的协议,如果一个客户端只是单纯地请求一个文件(HTML或GIF),服务器端可以响应给客户端,并不需要知道一连串的请求是否来自于相同的客户端,而且也不需要担心客户端是否处在连接状态. ...

  9. zookeeper curator客户端之增删改查

    zookeeper curator客户端之增删改查 zookeeper安装:https://www.cnblogs.com/zwcry/p/10272506.html curator客户端是Apach ...

随机推荐

  1. 201521123012 《Java程序设计》第八周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容. 1.2 选做:收集你认为有用的代码片段 2. 书面作业 1.本次作业题集集合 List中指定元素的删除(题目4 ...

  2. 201521123022 《Java程序设计》 第七周学习总结

    1. 本周学习总结 以你喜欢的方式(思维导图或其他)归纳总结集合相关内容. 2. 书面作业 Q1.ArrayList代码分析 Q1.1 解释ArrayList的contains源代码 ArrayLis ...

  3. Eclipse rap 富客户端开发总结(6) : 如何发布rap到tomcat

    1.先下载以来的打包插件 war products  输入下面的地址,选择相应的插件 新建一个 war product Configutation向导 下面的war  product Configut ...

  4. shell脚本命令,一些你在书上找不到的命令。

    1.!$<!$是一个特殊的环境变量,它代表了上一个命令的最后一个字符串.如:你可能会这样: $mkdir mydir$mv mydir yourdir$cd yourdir 可以改成: $mkd ...

  5. Oracle与Mysql区别简述

    在Mysql中,一个用户下可以创建多个库: 而在Oracle中,Oracle服务器是由两部分组成 数据库实例[理解为对象,看不见的] 数据库[理解为类,看得见的] 一个数据库实例可拥有多个用户,一个用 ...

  6. web网站更换新域名

    第一步.绑定新的域名到单独的空间 一般我们都是用的VPS或者不限制建站数量的虚拟主机,尽量的保持原有的IP不变,我这边在老站点同IP的VPS主机下新建一个新域名站点,这样我们可以确保原有的站点IP不变 ...

  7. jquery ocupload一键上传文件应用

    直接上栗子 这是官方文档栗子 var myUpload = $(element).upload({ name: 'file', action: '', enctype: 'multipart/form ...

  8. 关于maven中一些问题的解决尝试

    在maven中会遇到很多问题,pom.xml啊,数据库没有自动建表等等. 需要先把运行项目,所依赖的jar项目install安装一下,然后Maven --> update project 一下. ...

  9. stl 和并查集应用

    抱歉这么久才写出一篇文章,最近进度有点慢.这么慢是有原因的,我在想如何改进能让大家看系列文章的时候更方便一些,现在这个问题有了答案,在以后的推送中,我将尽量把例题和相关知识点在同一天推出,其次在代码分 ...

  10. Codevs1380没有上司的舞会_KEY

    没有上司的舞会 1380 没有上司的舞会 时间限制: 1 s 空间限制: 128000 KB 题目描述 Description Ural大学有N个职员,编号为1~N.他们有从属关系,也就是说他们的关系 ...