您好,登錄后才能下訂單哦!
Tomcat的Session持久化策略是什么,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。
關于Tomcat的Session,我們都知道默認是保存在內存中。為了解決重啟應用服務器Session丟失的問題,Tomcat內部的StandardManager會在正常的關閉時鈍化活動的Session 并在重啟的時候重新加載。
而Tomcat在StandardManager之外,還提供了對應持久化Session的Manager實現: PersistentManager,目前對應的有兩種持久化的實現
FileStore
JDBCStore
分別是將活動的Session保存在磁盤上和保存到數據庫中。
本次我們以FileStore為例,來分析下PersistentManager在Tomcat中的實現。
PersistentManager的配置基本上是這樣的:
<Manager className="org.apache.catalina.session.PersistentManager" debug="0" saveOnRestart="true" maxActiveSessions="-1" minIdleSwap="-1" maxIdleSwap="5" maxIdleBackup="3" > <Store className="org.apache.catalina.session.FileStore" directory="/home/mytestsession"/> </Manager>
對于FileStore和JDBCStore,基本配置都類似,有差異的只是Store中對應的具體屬性,比如JDBCStore需要額外指定數據的用戶名和密碼等。上面的配置可以直接 用于FileStore。
其中,像maxIdleBackup
、maxIdleSwap
、minIdleSwap
默認都是關閉的,默認值都是-1。當然,我們上面的配置是修改過的。默認的行為會和StandardManager一致,即在關閉重啟時進行Session的鈍化和解析。
而當按照我們上面的配置啟動Tomcat后,服務器會根據maxIdleBackup的時間,以秒為單位,進行空閑Session的持久化。在配置的目錄中,會生成以sessionId為文件名.session的文件
例如:5E62468BFF33CF7DE28464A76416B85E.session
主要參數說明:
saveOnRestart -當服務器關閉時,是否要將所有的session持久化;
maxActiveSessions - 可處于活動狀態的session數;
minIdleSwap/maxIdleSwap -session處于不活動狀態最短/長時間(s),sesson對象轉移到File Store中;
maxIdleBackup -大于這一時間時,會將session備份。
寫文件:
public void save(Session session) throws IOException { // Open an output stream to the specified pathname, if any File file = file(session.getIdInternal()); if (file == null) { return; } if (manager.getContext().getLogger().isDebugEnabled()) { manager.getContext().getLogger().debug(sm.getString(getStoreName() + ".saving", session.getIdInternal(), file.getAbsolutePath())); } try (FileOutputStream fos = new FileOutputStream(file.getAbsolutePath()); ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(fos))) { ((StandardSession)session).writeObjectData(oos); } }
我們來看load操作,和StandardManager加載Session基本一致,先創建空的session,再readObjectData:
public Session load(String id) { File file = file(id); Context context = getManager().getContext(); try (FileInputStream fis = new FileInputStream(file.getAbsolutePath()); ObjectInputStream ois = getObjectInputStream(fis)) { StandardSession session = (StandardSession) manager.createEmptySession(); session.readObjectData(ois); session.setManager(manager); return session; } catch (FileNotFoundException e) { return null; } }
刪除操作:
public void remove(String id) throws IOException { File file = file(id); file.delete();}
而這些load,remove等操作的觸發點,就是我們之前提到過的后臺線程:我們在前面分析過期的session是如何處理的時候,曾提到過,可以移步這里:對于過期的session,Tomcat做了什么?
都是使用backgroundProcess
public void backgroundProcess() { count = (count + 1) % processExpiresFrequency; if (count == 0) processExpires();}
在PersistentManager
的processExpires方法中,重點有以下幾行
processPersistenceChecks(); if (getStore() instanceof StoreBase) { ((StoreBase) getStore()).processExpires(); }
其中在processPersistenceChecks
中,就會對我們上面配置的幾項進行檢查,判斷是否要進行session文件的持久化等操作
/** * Called by the background thread after active sessions have been checked * for expiration, to allow sessions to be swapped out, backed up, etc. */public void processPersistenceChecks() { processMaxIdleSwaps(); processMaxActiveSwaps(); processMaxIdleBackups(); }
此外,通過配置pathname
為空,即可禁用session的持久化策略,在代碼中,判斷pathname為空時,不再創建持久化文件,從而禁用此功能。
<Manager pathname="" />
總結下,正如文檔中所描述,StandardManager所支持的重啟時加載已持久化的Session這一特性,相比PersistentManager只能算簡單實現。要實現更健壯、更符合生產環境的重啟持久化,最好使用PersistentManager并進行恰當的配置。
看完上述內容,你們掌握Tomcat的Session持久化策略是什么的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。