zookeeper源码_zookeeper源码分析之六session机制

4d35f48ae780a33366752aba77302c74.png

zookeeper中session意味着一个物理连接,客户端连接服务器成功之后,会发送一个连接型请求,此时就会有session 产生。

session由sessionTracker产生的,sessionTracker的实现有SessionTrackerImpl,LocalSessionTracker,LeaderSessionTracker(leader),LearnerSessionTracker(follow and oberser)四种实现。它们的分支由各自的zookeeperServer.startup()开始。

1.sessionTrackerImpl

标准zookeeperServer的实现

 public synchronized void startup() { if (sessionTracker == null) { createSessionTracker(); } startSessionTracker(); setupRequestProcessors(); registerJMX(); state = State.RUNNING; notifyAll(); }

其实现由sessionTrackerImpl来实现,其官方说明

/**

* This is a full featured SessionTracker. It tracks session in grouped by tick

* interval. It always rounds up the tick interval to provide a sort of grace

* period. Sessions are thus expired in batches made up of sessions that expire

* in a given interval.

*/

 protected void createSessionTracker() { sessionTracker = new SessionTrackerImpl(this, zkDb.getSessionWithTimeOuts(), tickTime, 1, getZooKeeperServerListener()); } protected void startSessionTracker() { ((SessionTrackerImpl)sessionTracker).start(); }

sessionTrackerImpl是一个线程,其run方法是真实逻辑:

 @Override public void run() { try { while (running) { long waitTime = sessionExpiryQueue.getWaitTime(); if (waitTime > 0) { Thread.sleep(waitTime); continue; } for (SessionImpl s : sessionExpiryQueue.poll()) { setSessionClosing(s.sessionId); expirer.expire(s); } } } catch (InterruptedException e) { handleException(this.getName(), e); } LOG.info("SessionTrackerImpl exited loop!"); }

sessionTrackerImpl实现了session的各种操作:创建session,检测session,删除session等。我们以增加session为例,看一下session机制:

 public long createSession(int sessionTimeout) { long sessionId = nextSessionId.getAndIncrement(); addSession(sessionId, sessionTimeout); return sessionId; } public synchronized boolean addSession(long id, int sessionTimeout) { sessionsWithTimeout.put(id, sessionTimeout); boolean added = false; SessionImpl session = sessionsById.get(id); if (session == null){ session = new SessionImpl(id, sessionTimeout); } // findbugs2.0.3 complains about get after put. // long term strategy would be use computeIfAbsent after JDK 1.8 SessionImpl existedSession = sessionsById.putIfAbsent(id, session); if (existedSession != null) { session = existedSession; } else { added = true; LOG.debug("Adding session 0x" + Long.toHexString(id)); } if (LOG.isTraceEnabled()) { String actionStr = added ? "Adding" : "Existing"; ZooTrace.logTraceMessage(LOG, ZooTrace.SESSION_TRACE_MASK, "SessionTrackerImpl --- " + actionStr + " session 0x" + Long.toHexString(id) + " " + sessionTimeout); } updateSessionExpiry(session, sessionTimeout); return added; }

上文中出现了一个nextSessionId,看一下其的生成方式:

 /** * Generates an initial sessionId. High order byte is serverId, next 5 * 5 bytes are from timestamp, and low order 2 bytes are 0s. */ public static long initializeNextSession(long id) { long nextSid; nextSid = (Time.currentElapsedTime() << 24) >>> 8; nextSid = nextSid | (id <<56); return nextSid; }

创建sessionImpl

红色代码所示。

更新过期时间并记录

 private void updateSessionExpiry(SessionImpl s, int timeout) { logTraceTouchSession(s.sessionId, timeout, ""); sessionExpiryQueue.update(s, timeout); } private void logTraceTouchSession(long sessionId, int timeout, String sessionStatus){ if (!LOG.isTraceEnabled()) return; String msg = MessageFormat.format( "SessionTrackerImpl --- Touch {0}session: 0x{1} with timeout {2}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值