本篇內(nèi)容主要講解“zk中的會話管理SessionTrackerImpl的方法”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“zk中的會話管理SessionTrackerImpl的方法”吧!
創(chuàng)新互聯(lián)是一家集網(wǎng)站建設,千陽企業(yè)網(wǎng)站建設,千陽品牌網(wǎng)站建設,網(wǎng)站定制,千陽網(wǎng)站建設報價,網(wǎng)絡營銷,網(wǎng)絡優(yōu)化,千陽網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強企業(yè)競爭力??沙浞譂M足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時我們時刻保持專業(yè)、時尚、前沿,時刻以成就客戶成長自我,堅持不斷學習、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實用型網(wǎng)站。
SessionTrackerImpl中包含實現(xiàn)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> getSessionExpiryMap() { // Convert time -> sessions map to time -> session IDs map Map > expiryMap = sessionExpiryQueue.getExpiryMap(); Map > sessionExpiryMap = new TreeMap >(); for (Entry > e : expiryMap.entrySet()) { Set ids = new HashSet (); 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; } //已經(jīng)超時了,拿出會話隊列中的會話進行清理 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) | 創(chuàng)建session,指定過期時間 |
trackSession(sessionId, sessionTimeout); | 取得sessionId,調(diào)用trackSession(sessionId, sessionTimeout);方法進行session創(chuàng)建,更新會話超時時間
|
@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;
}
會話建立之后,會話如何保持激活狀態(tài)
問題 會話如何遷移?
會話激活的方法有 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 什么時候會發(fā)出激活會話請求
1客戶端向服務端發(fā)送請求,包含讀寫請求,就會激活會話
2 客戶端發(fā)現(xiàn)在sessionTimeout/3時間內(nèi)未收到任何通信,就會向服務器發(fā)起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的方法”有了更深的了解,不妨來實際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關內(nèi)容可以進入相關頻道進行查詢,關注我們,繼續(xù)學習!