shiro實現session共享

session共享:在多應用系統中,若是使用了負載均衡,用戶的請求會被分發到不一樣的應用中,A應用中的session數據在B應用中是獲取不到的,就會帶來共享的問題。java

假設:用戶第一次訪問,鏈接的A服務器,進行了登陸操做進入了系統,當用戶再次操做時,請求被轉發到了B服務器,用戶並無在B進行登陸,此時用戶又來到了登陸頁面,這是難以理解和接受的,這就引出了session共享。git

對於shiro框架如何實現session的共享呢?shiro的共享分爲兩個方面,一個是session的共享,一個是cache的共享。接下來結合redis分別來實現這兩個方面。github

 

一.Session的共享redis

    

    shiro提供了本身的會話管理器sessionManager,其中有個屬性叫sessionDao它來處理全部的會話信息。數據庫

    對於sessionDao,shiro也提供了本身的實現,經常使用的是ehcache的實現。Ehcache是jvm級別的,多個應用就會產生多個緩存示例,沒法作到信息跨進程共享。要實現共享,就要重寫sessionDao,經過實現咱們本身的Dao,作到同一個會話信息的惟一性。緩存

看下面一幅類圖:服務器

1.繼承shiro提供的抽象sessionDao,重寫create,read,delete等方法。微信

2.考慮系統的擴展性,咱們抽象出一個數據倉儲接口,並提供一個redis的實現方式。假如之後咱們底層要換成數據庫存儲session數據,那隻需擴展一個數據庫的實現類並注入。session

 

二.Cache的共享負載均衡

 

一樣的,shiro也提供了本身的緩存管理器:cacheManager,重寫這個實現,來知足緩存的共享。

看下面的類圖:

  1. 咱們只需實現shiro的CacheManager和Cache接口便可。前者暴漏了獲取Cache實例的方法,後者提供了Cache實例的增刪改查操做。

  2. 中間一層的抽象是爲了設計的良好,提供擴展性,後期有須要,只需增長ShiroCacheManager的實現類。

  3. JedisShiroCacheManager中的Cache實例經過ConCurrentHashMap進行緩存,防止對象的反覆建立。

 

三.配置

 

3.1 Cache配置

<!-- redisManager-->

<bean id ="redisManager" class = "com.yingxinhuitong.shiro.util.RedisManager">
  <property name = "host"value = "127.0.0.1"/>
  <property name = "port"value = "6379"/>
  <property name = "expire"value = "1800"/>
  <!--<property name ="password" value=""/>-->
  <!--<property name ="timeout" value="0"/>-->
</bean>
<!-- shiro緩存 -->
<bean id = "shrioCacheManager" class ="com.yingxinhuitong.shiro.cache.JedisShiroCacheManager">

    <property name ="redisManager" ref = "redisManager"/>
</bean>
<bean id = "shiroJedisManager" class ="com.yingxinhuitong.shiro.cache.CustomShiroCacheManager">

    <property name ="shrioCacheManager" ref = "shrioCacheManager"/>
</bean>

 

3.2 sessionDao配置

<!-- 會話DAO -->

<bean id = "shiroSessionRepository"

  class = "com.yingxinhuitong.shiro.session.JedisShiroSessionRepository">

    <property name = "redisManager" ref = "redisManager"/></bean>

    <bean id = "sessionDAO" class = "com.yingxinhuitong.shiro.session.CustomShiroSessionDao"><property name = "sessionIdGenerator" ref = "sessionIdGenerator"/>

    <property name = "shiroSessionRepository" ref = "shiroSessionRepository"/>

</bean>

 

四.代碼

參見:https://github.com/zljk0306/shiro-redis-share

 

關注老薑談技術,微信號:helojava,或者掃描下面二維碼。

相關文章
相關標籤/搜索