如何通過 J2Cache 實現分佈式 session 存儲 原 薦

做 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 即可。例如:

<Context>
  ...
  <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
    memcachedNodes="n1:host1.yourdomain.com:11211,n2:host2.yourdomain.com:11211"
    sticky="false"
    sessionBackupAsync="false"
    lockingMode="uriPattern:/path1|/path2"
    requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
    transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
    />
</Context>

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

--------

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

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

使用方法:

1. Web 項目添加 J2Cache 的 session-manager 模塊依賴:

<dependency>
  <groupId>net.oschina.j2cache</groupId>  
  <artifactId>j2cache-session-manager</artifactId>  
  <version>1.0.0-beta4</version>  
</dependency>

2. 在 web.xml 中配置 Filter:

<filter>
    <filter-name>j2cache-session-filter</filter-name>
    <filter-class>net.oschina.j2cache.session.J2CacheSessionFilter</filter-class>
    <init-param><!-- 內存中存放會話數 -->
        <param-name>session.maxSizeInMemory</param-name>
        <param-value>2000</param-value>
    </init-param>
    <init-param><!-- 會話有效期,單位:秒鐘 -->
        <param-name>session.maxAge</param-name>
        <param-value>1800</param-value>
    </init-param>
    <!-- cookie configuration -->
    <init-param>
        <param-name>cookie.name</param-name>
        <param-value>J2CACHE_SESSION_ID</param-value>
    </init-param>
    <init-param>
        <param-name>cookie.path</param-name>
        <param-value>/</param-value>
    </init-param>
    <init-param>
        <param-name>cookie.domain</param-name>
        <param-value></param-value>
    </init-param>
    <!-- redis configuration -->
    <init-param>
        <param-name>redis.mode</param-name>
        <param-value>single</param-value>
    </init-param>
    <init-param>
        <param-name>redis.hosts</param-name>
        <param-value>127.0.0.1:6379</param-value>
    </init-param>
    <init-param>
        <param-name>redis.channel</param-name>
        <param-value>j2cache</param-value>
    </init-param>
    <init-param>
        <param-name>redis.cluster_name</param-name>
        <param-value>j2cache</param-value>
    </init-param>
    <init-param>
        <param-name>redis.timeout</param-name>
        <param-value>2000</param-value>
    </init-param>
    <init-param>
        <param-name>redis.password</param-name>
        <param-value></param-value>
    </init-param>
    <init-param>
        <param-name>redis.database</param-name>
        <param-value>0</param-value>
    </init-param>
    <init-param>
        <param-name>redis.maxTotal</param-name>
        <param-value>100</param-value>
    </init-param>
    <init-param>
        <param-name>redis.maxIdle</param-name>
        <param-value>10</param-value>
    </init-param>
    <init-param>
        <param-name>redis.minIdle</param-name>
        <param-value>1</param-value>
    </init-param>
</filter>

<filter-mapping>
    <filter-name>j2cache-session-filter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

3. 啓動應用,即可開啓分佈式 session 存儲。

當重啓 Web 應用時,內存中的 session 數據爲空,會自動從 redis 中讀取重啓前保存的 session 數據。所有節點又通過 redis 進行 session 數據的共享,當有 session 數據更新時會通過 Redis Pub/Sub 來通知其他節點重新從 Redis 中讀取數據,確保不同節點的 session 數據是一致的。

sesson-manager 模塊代碼 https://gitee.com/ld/J2Cache/tree/master/modules/session-manager

很簡單吧?  去 https://gitee.com/ld/J2Cache 點個贊吧?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章