本文介绍在使用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. JS查错小工具-三生有幸【推荐】

    H5和CSS语言在开发者官网上都有在线查错工具,同样的,更加复杂的JavaScript也需要一个查错工具,(别指望DreamWeaver了,debug功能做的太垃圾,还不如Firefox自带的强..) ...

  2. 必应app测试

    一.app评测 1.个人使用体验 第一次使用必应app看到是微软这么一个大公司做的英语词典,应该会很有名但是我居然没有听说过.当我打开这个软件使用的时候看到界面的视频感觉还不错.但是总感觉这样的app ...

  3. 201521123092《java程序设计》第五周学习总结

    1.本周学习总结 #1.1 尝试使用思维导图总结有关多态与接口的知识点. 2.书面作业 #1.代码阅读:Child压缩包内源代码##1.1 com.parent包中Child.java文件能否编译通过 ...

  4. 201521123033《Java程序设计》第4周学习总结

    1. 本周学习总结 1.1 尝试使用思维导图总结有关继承的知识点. answer: 1.2 使用常规方法总结其他上课内容. answer:学了继承以及各种关键字 2. 书面作业 1.注释的应用 使用类 ...

  5. 201521123057 《Java程序设计》第10周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常与多线程相关内容. 2. 书面作业 本次PTA作业题集异常.多线程 1.finally 题目4-2 1.1 截图你的提交结果(出 ...

  6. 读取指定excel,修改并某个值并另存到指定路径

    HSSFWorkBook是解析excel2007以前的版本(xls)之后的版本使用XSSFWrokBook(xlsx) 附:处理excel2007之后的版本代码: package gbyp.autoQ ...

  7. Oracle游标详解大全

    本文出自: http://www.cnblogs.com/sc-xx/archive/2011/12/03/2275084.html -- 声明游标:CURSOR cursor_name IS sel ...

  8. eclipse安装java ee插件方法步骤

    1.本人以前使用的MyEclipse进行Javaweb开发,但是后来由于myeclipse实在太臃肿,经常在运行的过程中不流畅 (可能电脑内存也不是太高吧)   !所以坚决换用eclipse,但是问题 ...

  9. 再起航,我的学习笔记之JavaScript设计模式24(备忘录模式)

    备忘录模式 概念介绍 备忘录模式(Memento): 在不破坏对象的封装性的前提下,在对象之外捕获并保存该对象内部的状态以便日后对象使用或者对象恢复到以前的某个状态. 简易分页 在一般情况下我们需要做 ...

  10. [UIKit学习]01.关于UIView,frame,bounds,center

    UIView是Cocoa大多控件的父类,本身不带事件. UIView的常见用法 @property(nonatomic,readonly) UIView *superview; 获得自己的父控件对象 ...