如何通過J2Cache實現分散式session儲存

技術小能手發表於2018-09-27

做 Java Web 開發的人多數都會需要使用到 session (會話),我們使用 session 來儲存一些需要在兩個不同的請求之間共享資料。一般 Java 的 Web 容器像 Tomcat、Resin、Jetty 等等,它們會在記憶體中儲存 session 資料。這樣做會有兩個不足:

1.服務重啟後 session 資料丟失

2.應用做叢集部署的時候,不同的節點無法共享 session 資料

我們以使用比例最高的 Tomcat 為例,針對第二個問題 Tomcat 提供了叢集 session 複製的解決方案,詳情請看官方文件。看完文件你會發現 Tomcat 自帶的方法配置非常複雜,而且它沒有解決第一個問題 —— 服務重啟導致 session 資料丟失的問題。

現在還有另外一種方案就是使用 memcached 或者是 redis 來儲存 session 資料,於是就有了這麼一些開源專案:

這些開源專案使用和配置都比較簡單,而且對應用完全透明,只需要在 server.xml 中配置好 Manager 即可。例如:


但是這幾個開源專案都有一個最根本的問題沒法解決,當存放在 session 中的資料量比較大,而且讀取 session 資料非常頻繁時會導致 memcached 或者是 redis 吞吐量受頻寬限制使得效能變得非常差。逼迫你必須通過 memcached 或者 redis 的擴容和叢集來解決問題,大大的增加了硬體投入的成本和運維的成本。

——–

那麼用 J2Cache 的 session-manager 模組就可以有效解決前面提到的所有問題。J2Cache 在 redis 的基礎上引入了記憶體快取的概念,可以確保服務重啟後 session 資料不會丟失,其次極大的降低了 redis 的資料吞吐量,保證在高併發情況下依然有很好的效能表現。

與前面提到的幾個開源專案不同,J2Cache 的 session manager 採用 Filter 方式實現,支援各種 Java 的 Web 容器服務。

使用方法:

1. Web 專案新增 J2Cache 的 session-manager 模組依賴:


2. 在 web.xml 中配置 Filter:


3. 啟動應用,即可開啟分散式 session 儲存。

當重啟 Web 應用時,記憶體中的 session 資料為空,會自動從 redis 中讀取重啟前儲存的 session 資料。所有節點又通過 redis 進行 session 資料的共享,當有 session 資料更新時會通過 Redis Pub/Sub 來通知其他節點重新從 Redis 中讀取資料,確保不同節點的 session 資料是一致的。

本文來自雲棲社群合作伙伴“開源中國”

本文作者:王練

原文連結


相關文章