Tomcat下 session 持久化問題(重啟服務器session 仍然存在)


感謝大佬:https://www.iteye.com/blog/xiaolongfeixiang-560800

關於在線人數統計,大都使用SessionListener監聽器實現。

SessionListener 觸發源:

1、Session Create 時

2、Session timeout 時

3、顯式調用session的invalidate方法 時

4、在Tomcat設置Session持久化為FALSE的情況下,Tomcat關閉時,觸發Session destroy事件

5、在Tomcat設置Session持久化為TRUE的情況下,Tomcat重啟后,檢測到Session超時時,觸發Session destroy事件(可歸入第2中情況中)

如何Tomcat Session持久化配置?

在默認的情況下,Tomcat6是提供了這項功能的。請查看$TOMCAT_HOME$/conf/context.xml。在大概24行,你會看到注釋:

<!-- Uncomment this to disable session persistence across Tomcat restarts -->  
<!-- <Manager pathname="" /> -->  

這說明默認的Tomcat是支持Session持久化的。當然,取消注釋也就取消了這個功能。

Session持久化&不持久化

如果Tomcat配置為Session的不持久化,在Tomcat關閉時,會自動觸發Session destroy事件。

如果Tomcat配置為Session的持久化,在Tomcat關閉時,不會觸發Session destroy事件。而是將每個Session中內容寫入到文件中。當Tomcat再次啟動時,會讀取該參數,並且驗證Session是否 TimeOut(但是這個驗證似乎有點延遲,大概幾秒鍾吧。如果檢測到超時,則Tomcat會自動觸發Session Destroy事件)。

失敗案例分析:

最近在分析一個其他人寫的應用中,發現在線人數出現負數的情況。原因是沒有修改Tomcat的默認配置,因此Session的持久化功能是開啟的。當 Tomcat重啟后,由於在線人數是Listener中的Static常量,所以重啟后會歸零。重啟后,如果觸發了Session Destroy事件,那么就會出現在線人數為負的情況。

但是,重啟后用戶的什么操作會觸發Session Destroy事件呢?

首先,1個大前提是用戶的瀏覽器在Tomcat重啟的間隔都一直存在,且未進行其他操作。(很簡單,如果在重啟期間,進行任何操作的話,肯定會看到“服務器無法響應”的錯誤信息,自然就離開了。也就不會有以后了。。)

然后,分2種情況:

情形1: 如果Tomcat關閉的時間大於Session的超時時間。Tomcat會自動地觸發Session Destroy事件。上面已經說了,這個“自動”是有延遲的。如果用戶進行任何操作,都會立即觸發Session Destroy事件。

情形2:如果Tomcat的關閉時間小於Session的超時時間,那么用戶點擊“注銷”等類似的注銷功能、或者Session超時,就會觸發Session Destroy事件。

解決的辦法:

方案1:關閉Tomcat Session 持久化的功能。取消那句注釋即可。

方案2:將在線人數存放在數據庫中,每次改變在線人數,都要訪問數據庫。(加重了數據庫訪問量)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM