Session活化、鈍化

Session活化:從硬盤上讀取序列化的session到內存中
Session鈍化:把內存中的session序列化到硬盤上

Tomcat中兩種Session鈍化管理器

session鈍化機制是由sessionManager管理 
tomcat提供了以下這兩種session處理方式

1
2
org.apache.catalina.session.StandarManager
org.apache.catalina.session.Persistentmanager

StandarManager是tomcat的session默認處理方式,如果配置Persistentmanager則使用Persistentmanager,沒有配置則使用StandarManager。

1. StandarManager

當Tomcat服務器關閉或者重啓時tomcat服務器會將當前內存中的session對象鈍化到服務器文件系統中;
另一種情況是web應用程序被重新加載時(其實原理也是重啓tomcat),內存中的session對象也會被鈍化到服務器的文件系統中
當系統啓動時,會把序列化到硬盤上session重新加載到內存中來。這樣用戶還保持這登錄狀態,提供系統的可用性。

只有在tomcat關閉和啓動的時候纔會活化和鈍化session 強制kill掉tomcat是不會把session鈍化到硬盤上的。

2. Persistentmanager

可以將內存中長時間不用的session鈍化到硬盤上,減少內存的佔用。

比如:當網站有大量用戶訪問的時候,服務器會創建大量的session,會佔用大量的服務器內存資源,當用戶開着瀏覽器一分鐘不操作頁面的話建議將session鈍化,將session生成文件放在tomcat工作目錄下。

那怎麼該設置呢?

在 /WebRoot/META-INF 目錄下創建 context.xml文件(也可以在tomca目錄下的其他四個地方創建,在這裏建是爲了只對這個網站起作用),配置如下:

1
2
3
4
5
6
<!--?xml version="1.0" ?--> 
<context> 
    <manager classname="org.apache.catalina.session.PersistentManager" maxidleswap="1"
        <store classname="org.apache.catalina.session.FileStore" directory="sessionDir"
    </store></manager> 
</context>
<h2 id="standarmanager-源碼分析">StandarManager 源碼分析

Session活化 doLoad() 方法

在當前程序重新啓動的時候,調用doLoad() 方法進行活化session
\
1. 清空sessions中的session(剛啓動,sessions中應該是沒有session的)

1
protected Map<string, session=""> sessions = new ConcurrentHashMap<>();</string,>
判斷是否有鈍化的session文件。如果沒有則結束加載session,如果有文件,則進行下面的加載session

\
1. 獲取當前項目的WebappClassLoader
2. 從硬盤中讀取session,並把session反序列化成StandardSession對象。然後激活當前的session,並判斷當前session是否過期

activate() 方法

\
這個方法迭代執行了所有在web.xml中註冊的session活化的listener監聽器。

expire() 方法

\
expire方法是判斷session是否過期,如果過期則執行所有在web.xml中註冊過所有的HttpSessionListener的sessionDestroyed()方法

Session鈍化 unLoad() 方法

在當前程序關閉的時候,調用unLoad() 方法進行鈍化session

\
1. 獲取輸出文件流
2. 遍歷內存中所有的session,並把session序列化到硬盤文件中。
3. 把序列化過的session置爲不可用,並重置session中的所有屬性。

PersistentManager 源碼分析

1. session 鈍化

通過 ContainerBase.startInternal() -> threadStart() 開啓一個線程,定時的輪詢所有的session,把長時間不使用(或者超出最大數量等)的session鈍化到硬盤上。

threadStart()

\

\
每隔backgroupProcessorDelay時間輪詢處理session。

processPersistenceChecks()

PersistentManagerBase.processExpires() -> processPersistenceChecks()
\
Tomcat只是在下面三種情況會將Session通過Store保存起來:
1. 當Session的空閒時間超過minIdleSwap和maxIdleSwap時,會將Session換出
2. 當Session的空閒時間超過maxIdleBackup時,會將Session備份出去
3. 當Session總數大於maxActiveSession時,會將超出部分的空閒Session換出

下面只分析下第一種情況的源碼processMaxIdleSwaps() 方法

processMaxIdleSwaps()

\
1. 判斷Session的空閒時間超過minIdleSwap和maxIdleSwap值。
2. 如果超過則通過 swapOut() 方法把session鈍化到硬盤上。

swapOut() 方法

\
1. 通過passivate() 方法調用web.xml 中註冊的HttpSessionActivationListener事件(同StandardSession)
2. 調用writeSession() 方法把session鈍化到指定的地方
3. 從sessions 中把session移除
4. 重置session,等待垃圾收集器回收此session。

writeSession()

\
調用store把session存儲到指定的地方,如下面的配置,是把session鈍化到硬盤文件中。

1
<store classname="org.apache.catalina.session.FileStore" directory="sessionDir">  </store>

2. session 活化

\
1. 當請求中獲取session時,先從調用findSession() 從內存sessions 中查找。
2. 如果內存中找不到 則調用 swapIn() 方法,進行查找,判斷該session是否鈍化了,如果鈍化則把該session活化加載到內存。

swapIn() 方法

\
爲當前查找的session設置一個lock。

\
1. 雙重檢查,在鎖中再次判斷sessions中是否有此session。
2. 從store中加載session。
3. 如果store 有此session 並判斷該session是否過期,並做處理

\
1. 通過tellNew() 調用 web.xml 中註冊HttpSessionListener的事件
2. 把session添加到sessions 集合中。
3. 通過activate()方法調用web.xml中註冊的HttpSessionActivationListener事件
4. 最後把該session相關的鎖,刪除。

發佈了14 篇原創文章 · 獲贊 7 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章