您好,登錄后才能下訂單哦!
本篇內容主要講解“zk中的會話管理SessionTrackerImpl的方法”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“zk中的會話管理SessionTrackerImpl的方法”吧!
SessionTrackerImpl中包含實現SessionImpl繼承Session(在SessionTracker中) SessionTracker接口
SessionImpl是session屬性集合類
屬性
sessionsById | sessionid和會話的對應map |
sessionExpiryQueue | 會話到期隊列 |
sessionsWithTimeout | sessionid對應過期時間 |
nextSessionId | 下一個sessionid |
expirer | 讓session過期,獲取服務id |
running | 運行中 |
涉及到的類ExpiryQueue
類SessionImpl
類SessionExpirer
會話管理功能主要有:
1 會話過期
2 設置會話超時時間
3 生成下一個會話id
方法
將time->sessions map轉成time->sessionIds 映射
getSessionExpiryMap
public synchronized Map<Long, Set<Long>> getSessionExpiryMap() { // Convert time -> sessions map to time -> session IDs map Map<Long, Set<SessionImpl>> expiryMap = sessionExpiryQueue.getExpiryMap(); Map<Long, Set<Long>> sessionExpiryMap = new TreeMap<Long, Set<Long>>(); for (Entry<Long, Set<SessionImpl>> e : expiryMap.entrySet()) { Set<Long> ids = new HashSet<Long>(); sessionExpiryMap.put(e.getKey(), ids); for (SessionImpl s : e.getValue()) { ids.add(s.sessionId); } } return sessionExpiryMap; }
run 超時會話檢查線程,更新超時時間
public void run() { try { while (running) { //沒有超時,需要等待超時時間 long waitTime = sessionExpiryQueue.getWaitTime(); //線程等待一段時間 if (waitTime > 0) { Thread.sleep(waitTime); continue; } //已經超時了,拿出會話隊列中的會話進行清理 for (SessionImpl s : sessionExpiryQueue.poll()) { ServerMetrics.getMetrics().STALE_SESSIONS_EXPIRED.add(1); //將標記設置為SessionImpl isClosing true setSessionClosing(s.sessionId); //zookeeperServer讓session過期 expirer.expire(s); } } } catch (InterruptedException e) { handleException(this.getName(), e); } LOG.info("SessionTrackerImpl exited loop!"); }
方法 | 說明 |
getSessionTimeout | 通過sessionId獲取超時時間 |
setSessionClosing | 設置會話關閉 |
removeSession | 通過sessionId移除會話,同時移除會話相關的映射關系圖 |
createSession(int sessionTimeout) | 創建session,指定過期時間 |
trackSession(sessionId, sessionTimeout); | 取得sessionId,調用trackSession(sessionId, sessionTimeout);方法進行session創建,更新會話超時時間
|
@Override public synchronized boolean trackSession(long id, int sessionTimeout) { boolean added = false; SessionImpl session = sessionsById.get(id); //沒有就新增一個session對象 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; if (LOG.isDebugEnabled()) { 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; }
方法 | 說明 | 涉及異常 |
commitSession(long id, int sessionTimeout) | 提交session | UnknownSessionException |
isTrackingSession(long sessionId) | 是否為可以追蹤會話,說明會話有效 | SessionExpiredException |
checkSession(long sessionId, Object owner) | 通過會話和擁有者檢查會話信息 | SessionMovedException |
分桶策略
將不同超時時間的會話分配到不同的桶中,做到有效管理,按照時間間隔來分桶
private long roundToNextInterval(long time) {
return (time / expirationInterval + 1) * expirationInterval;
}
會話建立之后,會話如何保持激活狀態
問題 會話如何遷移?
會話激活的方法有 public synchronized boolean touchSession(long sessionId, int timeout) { //獲取會話 SessionImpl s = sessionsById.get(sessionId); if (s == null) { logTraceTouchInvalidSession(sessionId, timeout); return false; } //關閉 if (s.isClosing()) { logTraceTouchClosingSession(sessionId, timeout); return false; } //更新會話 將舊過期時間桶中session移動到新桶 updateSessionExpiry(s, timeout); return true; }
client 什么時候會發出激活會話請求
1客戶端向服務端發送請求,包含讀寫請求,就會激活會話
2 客戶端發現在sessionTimeout/3時間內未收到任何通信,就會向服務器發起ping請求,
服務端收到請求后,就會進行會話激活操作
超時檢測策略
對于會話超時檢測而言,zookeeper使用SessionTracker負責,sessionTracker使用單獨線程(超時檢查線程)
專門進行會話超時檢測,即逐個一次地對會話桶中剩余會話進行清理。
如果一個會話被激活,那么zookeeper會將其從上一個會話桶遷移到下一個會話桶中,
如ExpirationTIme 1的session n遷移到ExpirationTime n桶中,此時ExpirationTime 1中留下的會話就是沒有被激活的
超時檢測程序就定時檢查這個會話桶中剩余未被遷移的會話,并且只在指定時間點上檢查(ExpirationTime 1,ExpirationTime2,
ExpirationTime3,...n)這樣有利于提高性能
@Override public void run() { try { while (running) { long waitTime = sessionExpiryQueue.getWaitTime(); if (waitTime > 0) { Thread.sleep(waitTime); continue; } for (SessionImpl s : sessionExpiryQueue.poll()) { ServerMetrics.getMetrics().STALE_SESSIONS_EXPIRED.add(1); setSessionClosing(s.sessionId); expirer.expire(s); } } } catch (InterruptedException e) { handleException(this.getName(), e); } LOG.info("SessionTrackerImpl exited loop!"); }
到此,相信大家對“zk中的會話管理SessionTrackerImpl的方法”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。