session共享:在多應用系統中,如果使用了負載均衡,用戶的請求會被分發到不同的應用中,A應用中的session數據在B應用中是獲取不到的,就會帶來共享的問題。
假設:用戶第一次訪問,連接的A服務器,進行了登錄操作進入了系統,當用戶再次操作時,請求被轉發到了B服務器,用戶並沒有在B進行登錄,此時用戶又來到了登錄頁面,這是難以理解和接受的,這就引出了session共享。
對於shiro框架如何實現session的共享呢?shiro的共享分為兩個方面,一個是session的共享,一個是cache的共享。接下來結合redis分別來實現這兩個方面。
一.Session的共享
shiro提供了自己的會話管理器sessionManager,其中有個屬性叫sessionDao它來處理所有的會話信息。
對於sessionDao,shiro也提供了自己的實現,常用的是ehcache的實現。Ehcache是jvm級別的,多個應用就會產生多個緩存示例,無法做到信息跨進程共享。要實現共享,就要重寫sessionDao,通過實現我們自己的Dao,做到同一個會話信息的唯一性。
看下面一幅類圖:
1.繼承shiro提供的抽象sessionDao,重寫create,read,delete等方法。
2.考慮系統的擴展性,我們抽象出一個數據倉儲接口,並提供一個redis的實現方式。假如以後我們底層要換成數據庫存儲session數據,那只需擴展一個數據庫的實現類並注入。
二.Cache的共享
同樣的,shiro也提供了自己的緩存管理器:cacheManager,重寫這個實現,來滿足緩存的共享。
看下面的類圖:
我們只需實現shiro的CacheManager和Cache接口即可。前者暴漏了獲取Cache實例的方法,後者提供了Cache實例的增刪改查操作。
中間一層的抽象是為了設計的良好,提供擴展性,後期有需要,只需增加ShiroCacheManager的實現類。
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,或者掃描下面二維碼。