ZooKeeper个人笔记Session管理
Session
1.sessionId <机器的SID,当前时间>生成一个sessionId,这是全局唯一的。
2.TimeOut 会话的超时时间,注意,这个值和客户端ZooKeeper对象指定的超时不一定相同
3.TickTime
4.isClosing 当SessionTracker检测到会话已经失效了,就会将这个会话的isClosing标记为true,之后这个会话将不在处理任何新的请求
SessionTracker
SessionTracker负责管理Session的整个会话生命周期。
SessionTracker的创建
如何管理多个session?
ExpireTime1 [session,session,session]
ExpireTime2 [session,session,session]
新创建的Session,其expireTime=curTime+SessionTimeout
leader服务器每隔expirationInterval时间就进行会话超时检查。
客户端向服务器发送请求,服务器就进行一次会话激活
客户端如果在sessionTimeout/3时间内,没有向服务器发送过任何请求,就主动发送一个PING请求,服务器收到
该请求后激活会话。
创建SessionTracker
在org.apache.zookeeper.server.ZooKeeperServer的startup方法中,会创建SessionTracker,然后启动它。
public void startup() {
if (sessionTracker == null) {
createSessionTracker();
}
//SessionTrackerImpl继承了Thread,因此实际上他也是个线程,这里就是调用start方法执行线程。
startSessionTracker();
setupRequestProcessors();
registerJMX();
synchronized (this) {
running = true;
notifyAll();
}
}
protected void createSessionTracker() {
sessionTracker = new SessionTrackerImpl(this, zkDb.getSessionWithTimeOuts(),
tickTime, 1);
}
激活会话
synchronized public boolean touchSession(long sessionId, int timeout) {
if (LOG.isTraceEnabled()) {
ZooTrace.logTraceMessage(LOG,
ZooTrace.CLIENT_PING_TRACE_MASK,
"SessionTrackerImpl --- Touch session: 0x"
+ Long.toHexString(sessionId) + " with timeout " + timeout);
}
//获取Session
SessionImpl s = sessionsById.get(sessionId);
// Return false, if the session doesn't exists or marked as closing
if (s == null || s.isClosing()) {
return false;
}
//计算超时时间点
long expireTime = roundToInterval(System.currentTimeMillis() + timeout);
//表明没有超时
if (s.tickTime >= expireTime) {
// Nothing needs to be done
return true;
}
//将Session从旧的set移动到新的set中
//首先取出tickTime对应的set,然后从set中移除掉Session
SessionSet set = sessionSets.get(s.tickTime);
if (set != null) {
set.sessions.remove(s);
}
//迁移到新的set中
s.tickTime = expireTime;
set = sessionSets.get(s.tickTime);
if (set == null) {
set = new SessionSet();
sessionSets.put(expireTime, set);
}
set.sessions.add(s);
return true;
}
会话超时检查
@Override
synchronized public void run() {
try {
while (running) {
currentTime = System.currentTimeMillis();
//如果还未超时
if (nextExpirationTime > currentTime) {
this.wait(nextExpirationTime - currentTime);
continue;
}
SessionSet set;
//已经超时了,很粗暴的直接从sessionSets中移走过期的session,这里做的真是太棒了
set = sessionSets.remove(nextExpirationTime);
if (set != null) {
//将每一个过期的session标记为close。
for (SessionImpl s : set.sessions) {
setSessionClosing(s.sessionId);
//注意这里哦,很重要的。这里就是调用ZooKeeperServer.expire来关闭session
expirer.expire(s);
}
}
//计算新的过期时间
nextExpirationTime += expirationInterval;
}
} catch (InterruptedException e) {
LOG.error("Unexpected interruption", e);
}
LOG.info("SessionTrackerImpl exited loop!");
}
public void expire(Session session) {
long sessionId = session.getSessionId();
LOG.info("Expiring session 0x" + Long.toHexString(sessionId)
+ ", timeout of " + session.getTimeout() + "ms exceeded");
//因为会话已经超时了,所以关闭它
close(sessionId);
}
private void close(long sessionId) {
submitRequest(null, sessionId, OpCode.closeSession, 0, null, null);
}
清理会话
找出这个session创建的所有临时节点,就是去ZooKeeper内存数据库中,根据sesionID来获取这个session创建的所有的临时节点信息,对每一个节点创建节点删除请求,从内存数据库中移除该会话的临时节点。
将session从SessionTrackerImpl中移除
关闭ServerCnxn。
KeeperException.ConnectionLoseException
客户端捕获到这种异常,只需要简单的等待org.apache.zookeeper.ZooKeeper自动重新连接上一个ZooKeeper机器即可,当重新连上了之后,客户端会受到Sync_Connected通知。
SESSION_EXPIRED
由于客户端在会话超时时间内没有向服务器发送PING,服务器认为会话已经过期,然后就会将其标记为失效了。如果之后客户端重新连接上了某一个机器,那么就会出现会话过期异常了。在这种情况下,只能创建一个新的ZooKeeper对象,建立一个新的会话了。
SessionMovedException
ZooKeeper个人笔记Session管理的更多相关文章
- Session管理解决方案笔记
大型网站Session管理解决方案: 1. web服务器之间的session复制. 优点:方案成熟 缺点:复制的性能开销大 2. 减少session使用,使用客户端存储cookie ...
- how tomcat works 读书笔记九 Session管理
在看本文之前,请先查阅相关Session与Cookie的资料. 这篇资料不错 http://blog.csdn.net/fangaoxin/article/details/6952954 Catali ...
- hibernate学习笔记第七天:二级缓存和session管理
二级缓存配置 1.导入ehcache对应的三个jar包 ehcache/*.jar 2.配置hibernate使用二级缓存 2.1设置当前环境开始二级缓存的使用 <property name=& ...
- ZooKeeper 学习笔记
ZooKeeper学习笔记 1. zookeeper基本概念 zookeeper是一个分布式的,开放源码的分布式应用程序协调服务,是hadoop和Habase的重要组件,是为分布式应用提供一致性服 ...
- ZooKeeper读书笔记
<ZooKeeper读书笔记> 1.Zookeeper是什么?Zookeeper是一个典型的分布式数据一致性的解决方案,分布式应用可以基于它实现诸如数据发布/订阅.负载均衡.命名服务.分布 ...
- ZooKeeper学习笔记(一)——概述
zookeeper学习笔记(一)--概述 1. 概述 Zookeeper是一个开源的分布式的,为分布式应用提供协调服务的Apache项目.zookeeper从设计模式的角度来理解:是一个基于观察者设计 ...
- Zookeeper学习笔记(中)
Zookeeper学习笔记(中) Zookeeper的基本原理和基本实现 深入了解ZK的基本原理 ZK的一致性: ZAB 协议: Zookeeper 原子消息广播协议 ZK通过选举保证 leader ...
- Zookeeper学习笔记(上)
Zookeeper学习笔记 本篇主要是一些基本的介绍和API的使用介绍, 有些只是记录了知识点,而没有完全在笔记中详细解释, 需要自行查找资料补充相关概念 主要参考了课程中的内容: Zookeeper ...
- How Tomcat works — 八、tomcat中的session管理
在使用shiro的session的时候感觉对于tomcat中session的管理还不是特别清楚,而且session管理作为tomcat中比较重要的一部分还是很有必要学习的. 目录 概述 session ...
随机推荐
- No module named migrate.versioning
在学习mega-tutorial的数据库章节时创建数据库遇到了问题,在stackoverflow上找到了结果 pip install sqlalchemy==0.7.9 pip install sql ...
- React.js入门笔记(续):用React的方式来思考
本文主要内容来自React官方文档中的"Thinking React"部分,总结算是又一篇笔记.主要介绍使用React开发组件的官方思路.代码内容经笔者改写为较熟悉的ES5语法. ...
- ThinkPhp 验证码不显示图片
验证码不显示原因分析: 1.先确保是否开启了 gd库 2.页面是否存在bom头 3.导入的ORG.Util.Image是否存在 4.入口文件中是否有define('APP_DEBUG', TRUE); ...
- [NHibernate]基本配置与测试
目录 写在前面 nhibernate文档 搭建项目 映射文件 持久化类 辅助类 数据库设计与连接配置 测试 总结 写在前面 一年前刚来这家公司,发现项目中使用的ORM是Nhibernate,这个之前确 ...
- SQL中SET和SELECT赋值的区别
最近的项目写的SQL比较多,经常会用到对变量赋值,而我使用SET和SELECT都会达到效果. 那就有些迷惑,这两者有什么区别呢?什么时候哪该哪个呢? 经过网上的查询,及个人练习,总结两者有以下几点主要 ...
- 使用phpMyAdmin修改MySQL数据库root用户密码
点击顶部的“SQL”标签进入sql命令输入界面.输入以下命令: update mysql.user set password=PASSWORD('snsgou$123456') where user= ...
- Linux进程间通信(一): 信号 signal()、sigaction()
一.什么是信号 用过Windows的我们都知道,当我们无法正常结束一个程序时,可以用任务管理器强制结束这个进程,但这其实是怎么实现的呢?同样的功能在Linux上是通过生成信号和捕获信号来实现的,运行中 ...
- Unix/Linux进程间通信(一):概述
序 Linux下的进程通信手段基本上是从Unix平台上的进程通信手段继承而来的.而对Unix发展做出重大贡献的两大主力AT&T的贝尔实验室及BSD(加州大学伯克利分校的伯克利软件发布中心)在进 ...
- Alpha版本十天冲刺——Day 1
站立式会议 会议总结 队员 今天完成 遇到的问题 明天要做 感想 鲍亮 α版本接口文档初步编写,任务统筹 绘制燃尽图出错 学习http资源访问,服务器请求接口demo测试 作为PM,之前对团队具体要做 ...
- javascript数据结构-数组
github博客地址 简介 数组是最简单的数据结构,javascript语言也很早就原声支持了数组Array数据类型,和其他语言略微不同的是:js中的数组可以存储不同类型的值,看起来很厉害的样子,但是 ...