Tomcat如何監(jiān)控并刪除超時(shí)Session詳解
偶然發(fā)現(xiàn)Tomcat會(huì)話(huà)時(shí)間的半小時(shí),并不是說(shuō)會(huì)話(huà)創(chuàng)建后,只有半小時(shí)的有效使用時(shí)間,而是說(shuō)會(huì)話(huà)空閑半小時(shí)后,會(huì)被刪除。索性就翻了一下源碼。做了一番整理。
注:空閑時(shí)間,指的是同一個(gè)會(huì)話(huà)兩次請(qǐng)求之間的間隔時(shí)間
Session相關(guān)類(lèi)圖

- HttpSession就是大家Servlet層可以直接使用的Session.
- Session是Tomcat內(nèi)部使用的接口,可以做一些內(nèi)部調(diào)用
- StandardSession是標(biāo)準(zhǔn)的HttpSession實(shí)現(xiàn),同時(shí)它也實(shí)現(xiàn)了Session接口,用于Tomcat內(nèi)部管理
- StandardSessionFacade,類(lèi)名已經(jīng)指明它就是一個(gè)“門(mén)面類(lèi)”,它內(nèi)部會(huì)引用一個(gè)StandardSession的對(duì)象,但對(duì)外只提供HttpSession規(guī)定的方法。
Manager相關(guān)類(lèi)圖

StandardManager與PersitentManager都是Manager的實(shí)現(xiàn),但是它們?cè)诖鎯?chǔ)Session對(duì)象的方式上有所不同。
StandarManager
1.Tomcat運(yùn)行時(shí),把Session存儲(chǔ)在內(nèi)存中
2.Tomcat關(guān)閉時(shí)(注意是正常的關(guān)閉操作,而非突然崩潰),會(huì)把Session寫(xiě)入到磁盤(pán)中,等到Tomcat重啟后再把Session加載進(jìn)來(lái)
PersistentManager
1.總是把Session存儲(chǔ)在磁盤(pán)中。
Manager與Context的關(guān)系
在Tomcat中,一個(gè)Context就是部署到Tomcat中的一個(gè)應(yīng)用(Webapp)。每一個(gè)Context都有一個(gè)單獨(dú)的Manager對(duì)象來(lái)管理這個(gè)應(yīng)用的會(huì)話(huà)信息。

Manager如何存儲(chǔ)Session
Manager對(duì)象會(huì)使用一個(gè)Map來(lái)存儲(chǔ)Session對(duì)象
- Key => SessionId
- Value => Session Object
/** * The set of currently active Sessions for this Manager, keyed by * session identifier. */ protected Map<String, Session> sessions = new ConcurrentHashMap<>();
當(dāng)一個(gè)請(qǐng)求到達(dá)Context的時(shí)候,如果它帶有JSESSIONID的Cookie,Manager就能依此找到關(guān)聯(lián)的Session對(duì)象,放入到Request對(duì)象中。
Manager的定期檢查
Manager接口有一個(gè)backgroundProcess()方法,顧名思義就是后臺(tái)處理。
/** * This method will be invoked by the context/container on a periodic * basis and allows the manager to implement * a method that executes periodic tasks, such as expiring sessions etc. */ public void backgroundProcess();
注:Container接口也有這個(gè)方法,這個(gè)方法一般在容器啟動(dòng)(start)的時(shí)候,開(kāi)啟一個(gè)額外的線(xiàn)程來(lái)執(zhí)行這個(gè)backgroundProcess方法。其中Context的這個(gè)方法啟動(dòng)后,會(huì)執(zhí)行Loader和Manager的backgroundProcess方法。
我們來(lái)看看這個(gè)方法都做了些什么?
/**
* {@inheritDoc}
* <p>
* Direct call to {@link #processExpires()}
*/
@Override
public void backgroundProcess() {
count = (count + 1) % processExpiresFrequency;
if (count == 0) //如果達(dá)到檢查頻率則開(kāi)始檢查
processExpires();
}
/**
* Invalidate all sessions that have expired.
*/
public void processExpires() {
long timeNow = System.currentTimeMillis();
Session sessions[] = findSessions(); //獲取所有session對(duì)象
int expireHere = 0 ; //過(guò)期session的數(shù)量,不要被這個(gè)變量名騙了
if(log.isDebugEnabled())
log.debug("Start expire sessions " + getName() + " at " + timeNow + " sessioncount " + sessions.length);
for (int i = 0; i < sessions.length; i++) {
if (sessions[i]!=null && !sessions[i].isValid()) {
expireHere++;
}
}
long timeEnd = System.currentTimeMillis();
if(log.isDebugEnabled()) //打印記錄
log.debug("End expire sessions " + getName() + " processingTime " + (timeEnd - timeNow) + " expired sessions: " + expireHere);
processingTime += ( timeEnd - timeNow );
}
很多人看到這里,可能會(huì)有跟我一樣的疑惑,即這里面根本就沒(méi)有使Session過(guò)期失效的操作,好像只做了狀態(tài)檢查。不過(guò)后來(lái)看到了Session的isValid方法的實(shí)現(xiàn)就都明白了。
/**
* Return the <code>isValid</code> flag for this session.
*/
@Override
public boolean isValid() {
if (!this.isValid) {
return false;
}
if (this.expiring) {
return true;
}
if (ACTIVITY_CHECK && accessCount.get() > 0) {
return true;
}
//關(guān)鍵所在
//如果有設(shè)置最大空閑時(shí)間
//就獲取此Session的空閑時(shí)間進(jìn)行判斷
//如果已超時(shí),則執(zhí)行expire操作
if (maxInactiveInterval > 0) {
int timeIdle = (int) (getIdleTimeInternal() / 1000L);
if (timeIdle >= maxInactiveInterval) {
expire(true);
}
}
return this.isValid;
}
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)本站的支持。
版權(quán)聲明:本站文章來(lái)源標(biāo)注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請(qǐng)保持原文完整并注明來(lái)源及原文鏈接。禁止復(fù)制或仿造本網(wǎng)站,禁止在非maisonbaluchon.cn所屬的服務(wù)器上建立鏡像,否則將依法追究法律責(zé)任。本站部分內(nèi)容來(lái)源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來(lái),僅供學(xué)習(xí)參考,不代表本站立場(chǎng),如有內(nèi)容涉嫌侵權(quán),請(qǐng)聯(lián)系alex-e#qq.com處理。
關(guān)注官方微信