ZooKeeper 会话超时
1、会话概述
在ZooKeeper中,客户端和服务端建立连接后,会话随之建立,生成一个全局唯一的会话ID(Session ID)。服务器和客户端之间维持的是一个长连接,在SESSION_TIMEOUT时间内,服务器会确定客户端是否正常连接(客户端会定时向服务器发送heart_beat,服务器重置下次SESSION_TIMEOUT时间)。因此,在正常情况下,Session一直有效,并且ZK集群所有机器上都保存这个Session信息。在出现网络或其它问题情况下(例如客户端所连接的那台ZK机器挂了,或是其它原因的网络闪断),客户端与当前连接的那台服务器之间连接断了,这个时候客户端会主动在地址列表(实例化ZK对象的时候传入构造方法的那个参数connectString)中选择新的地址进行连接。
2、连接断开
好了,上面基本就是服务器与客户端之间维持会话的过程了。在这个过程中,用户可能会看到两类异常CONNECTIONLOSS(连接断开)和SESSIONEXPIRED(Session过期)。连接断开(CONNECTIONLOSS)一般发生在网络的闪断或是客户端所连接的服务器挂机的时候,这种情况下,ZooKeeper客户端自己会首先感知到这个异常,具体逻辑是在如下方法中触发的:
- void org.apache.zookeeper.ClientCnxn.SendThread.run(){
- ……
- ……
- } catch (Throwable e) {
- if (closing) {
- if (LOG.isDebugEnabled()) {
- // closing so this is expected
- LOG.debug("An exception was thrown while closing send thread for session 0x"
- + Long.toHexString(getSessionId())
- + " : " + e.getMessage());
- }
- break;
- } else {
- // this is ugly, you have a better way speak up
- if (e instanceof SessionExpiredException) {
- LOG.info(e.getMessage() + ", closing socket connection");
- } else if (e instanceof SessionTimeoutException) {
- LOG.info(e.getMessage() + RETRY_CONN_MSG);
- } else if (e instanceof EndOfStreamException) {
- LOG.info(e.getMessage() + RETRY_CONN_MSG);
- } else if (e instanceof RWServerFoundException) {
- LOG.info(e.getMessage());
- } else {
- ……
- ……
- }
一种场景是Server服务器挂了,这个时候,ZK客户端首选会捕获异常,如下:
捕获异常后,ZK客户端会打印类似于如下日志:
- EndOfStreamException: Unable to read additional data from server sessionid 0x13ab17ad9ec000b, likely server has closed socket
然后做一些socket连接的善后工作。接下去是客户端重新选择一个Server Ip尝试连接,逻辑如代码C2-1所示,这里主要就是从地址列表中获取一个新的Server地址进行连接,关于这个地址如何获取,请查看这个文章:《ZooKeeper客户端地址列表的随机原理》。
- [C2-1]
- private void startConnect() throws IOException {
- state = States.CONNECTING;
- InetSocketAddress addr;
- if (rwServerAddress != null) {
- addr = rwServerAddress;
- rwServerAddress = null;
- } else {
- addr = hostProvider.next(1000);
- }
- LOG.info("Opening socket connection to server " + addr);
- setName(getName().replaceAll("\\(.*\\)",
- "(" + addr.getHostName() + ":" + addr.getPort() + ")"));
- try {
- zooKeeperSaslClient = new ZooKeeperSaslClient("zookeeper/"+addr.getHostName());
- } catch (LoginException e) {
- LOG.warn("SASL authentication failed: " + e + " Will continue connection to Zookeeper server without "
- + "SASL authentication, if Zookeeper server allows it.");
- eventThread.queueEvent(new WatchedEvent(
- Watcher.Event.EventType.None,
- Watcher.Event.KeeperState.AuthFailed, null));
- }
- clientCnxnSocket.connect(addr);
- }
程序运行过程中,整个过程日志打印大致如下:
- 2012-10-31 09:09:57,379 - INFO [main-SendThread(test.zookeeper.connection_string2:2181):zookeeper.ClientCnxn$SendThread@1053] - Unable to read additional data from server sessionid 0x23ab45c87df0000, likely server has closed socket, closing socket connection and attempting reconnect
- 收到事件通知:Disconnected
- 获取数据成功,path:/nileader
- 2012-10-31 09:09:58,293 - INFO [main-SendThread-zookeeper.ClientCnxn$SendThread@933] - Opening socket connection to server /1.2.1.1:2181
- 2012-10-31 09:09:58,294 - WARN [main-SendThread-client.ZooKeeperSaslClient@123] - SecurityException: java.lang.SecurityException: Unable to locate a login configuration occurred when trying to find JAAS configuration.
- 2012-10-31 09:09:58,295 - INFO [main-SendThread-client.ZooKeeperSaslClient@125] - Client will not SASL-authenticate because the default JAAS configuration section 'Client' could not be found. If you are not using SASL, you may ignore this. On the other hand, if you expected SASL to work, please fix your JAAS configuration.
- 2012-10-31 09:09:58,296 - INFO [main-SendThread-zookeeper.ClientCnxn$SendThread@846] - Socket connection established to test.zookeeper.connection_string/1.2.1.1:2181, initiating session
- 2012-10-31 09:09:58,299 - INFO [main-SendThread-zookeeper.ClientCnxn$SendThread@1175] - Session establishment complete on server test.zookeeper.connection_string/1.2.1.1:2181, sessionid = 0x23ab45c87df0000, negotiated timeout = 10000
- 收到事件通知:SyncConnected
所以,现在对于“连接断开”这个过程就一目了然了,核心流程如下:
ZK客户端捕获“连接断开”异常 ——> 获取一个新的ZK地址 ——> 尝试连接
在这个流程中,我们可以发现,整个过程不需要开发者额外的程序介入,都是ZK客户端自己会进行的,并且,使用的会话ID都是同一个,所以结论就是:发生CONNECTIONLOSS的情况,应用不需要做什么事情,等待ZK客户端建立新的连接即可。
CLOSED状态,应用要做的事情就是的看自己应用的复杂程序了,要重新实例zookeeper对象,然后重新操作所有临时数据(包括临时节点和注册Watcher),总之,会话超时在ZK使用过程中是真实存在的。
默认的Session超时时间是在2 * tickTime ~ 20 * tickTime。ZK实现如下,在这个方法中处理:
- ZooKeeperServer.processConnectRequest(ServerCnxn cnxn, ByteBuffer incomingBuffer)
所以,如果应用对于这个会话超时时间有特殊的需求的话,一定要和ZK管理员沟通好,确认好服务端是否设置了对会话时间的限制。
ZooKeeper 会话超时的更多相关文章
- zookeeper会话超时 链接超时的排查
1.会话概述 在ZooKeeper中,客户端和服务端建立连接后,会话随之建立,生成一个全局唯一的会话ID(Session ID).服务器和客户端之间维持的是一个长连接,在SESSION_TIMEOUT ...
- zookeeper系列之十一—zookeeper会话超时
1.会话概述 在Zookeeper中,客户端和服务端建立连接后,会话随之建立,生成一个全局唯一的会话ID(Session ID).服务器和客户端之间维持的是一个长连接,在SEESSION_TIMEOU ...
- 【分布式】Zookeeper会话
一.前言 前面分析了Zookeeper客户端的细节,接着继续学习Zookeeper中的一个非常重要的概念:会话. 二.会话 客户端与服务端之间任何交互操作都与会话息息相关,如临时节点的生命周期.客户端 ...
- Zookeeper会话
Zookeeper会话的状态可以分为以下四种:CONNECTING,CONNECTED,CLOSED和NOT_CONNECTED.下图展示了会话的状态和状态之间的转移过程: 会话的初始状态为NOT_C ...
- Zookeeper系列三:Zookeeper客户端的使用(Zookeeper原生API如何进行调用、ZKClient、Curator)和Zookeeper会话
一.Zookeeper原生API如何进行调用 准备工作: 首先在新建一个maven项目ZK-Demo,然后在pom.xml里面引入zk的依赖 <dependency> <groupI ...
- Zookeeper session超时
1.会话概述 在ZooKeeper中,客户端和服务端建立连接后,会话随之建立,生成一个全局唯一的会话ID(Session ID).服务器和客户端之间维持的是一个长连接,在SESSION_TIMEOUT ...
- ZooKeeper 会话的秘密
本文作者:HelloGitHub-老荀 Hi,这里是 HelloGitHub 推出的 HelloZooKeeper 系列,免费开源.有趣.入门级的 ZooKeeper 教程,面向有编程基础的新手. 项 ...
- (转)hbase master挂掉-zookeeper连接超时原因
link:http://www.51testing.com/?uid-445759-action-viewspace-itemid-812467 并行运行hbase删表,建表操作,多个表多个regio ...
- tomcat 会话超时设置
1.为单个WEB设置SESSION 在WEB.XML中添加 xml 代码 <session-config> <session-timeout>15</session-ti ...
随机推荐
- Unity UGUI图文混排(五) -- 一张图集对应多个Text
继上一篇说的更新了一张图集对应多个Text的功能,为了节省资源嘛 这里,但是也没有舍弃之前的一个Text一个图集,因为我感觉应该两个都有用,于是我重新写了一个脚本 1.其实大体跟前面的都没变,解析标签 ...
- 11 吐司 Toast 代码案例
package com.qf.day11_toast_demo05; import android.app.Activity; import android.graphics.Color; impor ...
- Spring之Enterprise JavaBeans (EJB) integration
原文地址:需要FQ https://translate.google.com/translate?hl=zh-CN&sl=zh-CN&tl=zh-CN&u=http%3A%2F ...
- Dynamics CRM2013 流程拷贝
在CRM中工作流是一个非常不错的功能,在实际业务场景中能满足各种业务需求.在我们设置一个工作流的时候,同一个实体一个逻辑功能可能需要多个工作流来实现,而多个工作流的不同之处可能只是启动时间或者是步骤中 ...
- Dynamics CRM2015 非基础语言环境下产品无法新建的问题
该现象出现在2015版本上,之前从没注意过这个问题不知道以前的版本是否存在. 我的安装包的基础语言是中文,第一张图有添加产品的按钮,切换到英文环境下后就没有了,一开始以为是系统做了隐藏处理,但用工具查 ...
- Android初级教程:shape的基本用法
转载本文请注明出处:http://blog.csdn.net/qq_32059827/article/details/52203347 点击打开链接 在自定义进度条之前,先来学习一下shape的用 ...
- Java基础---Java---网络编程---TCP的传输、客户端和服务端的互访、建立一个文本转换器、编写一个聊天程序
演示TCP的传输的客户端和服务端的互访 需求:客户端给服务端发送数据,服务端收到后,给客户端反馈信息. 客户端: 1.建立Socket服务,指定要连接方朵和端口 2.获取Socket流中的输出流,将数 ...
- iOS开发之二:UIWindow与UIView
1.UIWindow UIWindow 继承自UIView,它是整个应用的容器,一般来说一个应用就只有一个UIWindow. 如果不使用storyboard 时,需要我们自己创建UIWindow.实例 ...
- 流密码和RC4
定义:流密码是对称密码算法,从明文输入流逐位或逐字节产生密文输出. 实例:使用最广泛的流密码是RC4. 流密码结构: 流密码类似于”一次一密”,不同的是”一次一密”使用的是真正的随机数流,而流密码使用 ...
- 【Android 系统开发】 Android 系统启动流程简介
作者 : 万境绝尘 (octopus_truth@163.com) 转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/3889548 ...