1. 程式人生 > >Spring+Shiro+Redis實現tomcat叢集session共享問題

Spring+Shiro+Redis實現tomcat叢集session共享問題

最近在spring中集成了shiro框架並用redis實現session共享,發現專案啟動後執行時老是報錯,資訊如下:

org.apache.shiro.session.UnknownSessionException: There is no session with id [xxxx]的問題,具體問題如下圖:

org.apache.shiro.session.UnknownSessionException: There is no session with id [4B095106E5572FB4510462789898EF78]
	at org.apache.shiro.session.mgt.eis.AbstractSessionDAO.readSession(AbstractSessionDAO.java:170)
	at org.apache.shiro.session.mgt.DefaultSessionManager.retrieveSessionFromDataSource(DefaultSessionManager.java:236)
	at org.apache.shiro.session.mgt.DefaultSessionManager.retrieveSession(DefaultSessionManager.java:222)
	at com.sherlon.shiro.session.CustomSessionManager.retrieveSession(CustomSessionManager.java:36)
	at org.apache.shiro.session.mgt.AbstractValidatingSessionManager.doGetSession(AbstractValidatingSessionManager.java:118)
	at org.apache.shiro.session.mgt.AbstractNativeSessionManager.lookupSession(AbstractNativeSessionManager.java:148)
	at org.apache.shiro.session.mgt.AbstractNativeSessionManager.getSession(AbstractNativeSessionManager.java:140)
	at org.apache.shiro.mgt.SessionsSecurityManager.getSession(SessionsSecurityManager.java:156)
	at org.apache.shiro.mgt.DefaultSecurityManager.resolveContextSession(DefaultSecurityManager.java:460)
	at org.apache.shiro.mgt.DefaultSecurityManager.resolveSession(DefaultSecurityManager.java:446)
	at org.apache.shiro.mgt.DefaultSecurityManager.createSubject(DefaultSecurityManager.java:342)
	at org.apache.shiro.subject.Subject$Builder.buildSubject(Subject.java:845)
	at org.apache.shiro.web.subject.WebSubject$Builder.buildWebSubject(WebSubject.java:148)
	at org.apache.shiro.web.servlet.AbstractShiroFilter.createSubject(AbstractShiroFilter.java:292)
	at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:359)
	at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
	at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:347)
	at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:263)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
	at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:516)
	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1086)
	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:659)
	at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:285)
	at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2431)
	at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2420)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:745)

之後在網上搜索發現這有一個坑!原來shiro的DefaultWebSessionManager類中,預設Cookie名稱是JSESSIONID,與jetty, tomcat(如tomcat容器名也是JSESSIONID)等servlet容器名衝突,, 當跳出shiro servlet時,error-page容器會為JSESSIONID重新分配值導致登入會話丟失!

為了解決這個問題,在shiro配置中sessionManager里加上一個與容器不衝突的JSESSIONID就好了,如下:

        <!--sessionManager物件-->
	<bean id="sessionManager" class="com.sherlon.shiro.session.CustomSessionManager">
		<property name="sessionDAO" ref="redisSessionDao"/>
		<!-- 注意這裡是一個坑!!
		因為在shiro的DefaultWebSessionManager類中,預設Cookie名稱是JSESSIONID,
		這樣的話與servlet容器名衝突, 如jetty, tomcat等預設JSESSIONID,
		當跳出shiro servlet時如error-page容器會為JSESSIONID重新分配值導致登入會話丟失! -->
		<!-- 所以需要自己指定一個與專案執行容器不衝突的sessionID -->
		<property name="sessionIdCookie" ref="simpleCookie"/>
	</bean>
	<bean id="simpleCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
		<constructor-arg name="name" value="shiro.sesssion"/>
		<property name="path" value="/"/>
	</bean>

配置以上sessionIdCookie後,執行後正常。

相關推薦

Spring+Shiro+Redis實現tomcat叢集session共享問題

最近在spring中集成了shiro框架並用redis實現session共享,發現專案啟動後執行時老是報錯,資訊如下: org.apache.shiro.session.UnknownSessionException: There is no session with id

實現tomcat叢集session共享

第一種方案: 在負載均衡nginx中配置tomcat的session共享   可通過下面方法限制一個使用者訪問一個伺服器之後就只在該伺服器上操作。 第二種方案: 轉載:https://www.cnblogs.com/hafiz/p/7228294.html#autoid-2-0

spring,shiro,redis實現session共享

用到的redis jar如下 <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <

spring+shiro+redis實現session共享

利用spring的RedisTemplate實現session的存取,先配置applicationContext-shiro.xml <!-- 會話管理器 --> <bean id="sessionManager" class=

spring-boot+Redis實現簡單的分散式叢集session共享

  寫在前面:      首先宣告,筆者是一名Java程式設計屆的小學生。前面一直在幾家公司裡面做開發,其實都是一些傳統的專案,對於像分散式啦,叢集啦一些大型的專案接觸的很少,所以一直沒有自己整合和實現過。由於最近幾天專案不是很忙,自己又有點時間

shiro+redis實現叢集session共享

1.加入依賴 <dependency> <groupId>org.crazycake</groupId> <artifactId>shiro-redis</artifactId> <version>2.4.

spring session redis 實現叢集session共享,SessionListener監聽生效

pom主要配置 <properties> <spring.version>5.0.3.RELEASE</spring.version> <commons-lang.version

Spring boot + shiro + redis 實現session共享(偽單點登入)

    為實現Web應用的分散式叢集部署,要解決登入session的統一。本文利用shiro做許可權控制,redis做session儲存,結合spring boot快速配置實現session共享。注意本文未解決跨域的問題。不過對於一般的情況能夠很好的起到作用,具體已經在不同埠

使用Tomcat-redis-session-manager來實現Tomcat叢集部署中的Session共享

一、工作中因為要使用到Tomcat叢集部署,此時就涉及到了Session共享問題,

分散式叢集Session共享 簡單多tomcat8+redissession共享實現

什麼是Session/Cookie        使用者使用網站的服務,基本上需要瀏覽器與Web伺服器的多次互動。HTTP協議本身是無狀態的,當用戶的第一次訪問請求結束後,後端伺服器就無法知道下一次來訪問的還是不是上次訪問的使用者。我們需要基於HTTP協議支援會話狀態的機制,

Nginx shiro redistomcat共享session

pom.xml: <projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   xsi:s

shiro+cas+spring-data-redis實現多系統單點登入和分散式專案的session同步

CSDN開通很久了,但是一直沒寫東西,2018年了,這是我CSDN的第一篇文章,歡迎各位評論探討和指點。   一、背景: 現在公司的業務系統要做多臺分散式叢集,由於是web專案,要做session同步,想到的方案是用目前火熱的redis資料庫儲存session,還有業

SpringBoot整合Shiro,許可權的動態載入、更新,Shiro-Redis實現分散式Session共享

本文章是介紹SpringBoot整合Apache Shiro,並實現在專案啟動時從資料庫中讀取許可權列表,在對角色進行增刪改時,動態更新許可權以及在分散式環境下的Session共享,Session共享使用的是shiro-redis框架,是根據真實專案寫的一個Demo。網上有很

asp.net mvc 用Redis實現分散式叢集共享Session

1、這兩天研究Redis搞分散式session問題,網上找的資料都是用ServiceStack.Redis來實現的,但是在做效能測試的時候發現最新的v4版本有限制每小時候最多請求6000次,因為官網開始商業化要收費了,好坑爹的說,還好我前期弄了個性能測試列子,不然上線以後

分散式架構學習之:032--使用Redis3.0叢集實現Tomcat叢集Session共享

redis.properties # redis hosts ex: 127.0.0.1:6379, 127.0.0.2:6379, 127.0.0.2:6380, .... re

Redis 叢集session 共享

基本環境 Redis 2.4.10 Nginx 1.10.1 Tomcat 7 Jdk 7 Node1 :172.18.50.100 Node2 : 172.18.50.101 Nginx配置 #定義叢集的集合,將所有可用的node都新增到up

Tomcat伺服器叢集Session共享

新增session共享   這個是接上一篇文章的,不清楚的可以看這裡:   實現session共享的方式比較的簡單,就是在tomcat所部署的專案TestTomcat中,修改web.xml,在其中加入下面的資訊: <distribu

Nginx+Tomcat+Redis (負載均衡+session共享)完整案例

今天整合了一些資源,做了一個Nginx+Tomcat+Redis的案例,使部署的web專案能夠承載較大的訪問壓力,Nginx實現負載均衡,並使用Redis實現session共享; 如下拓撲圖: 各版本如圖所示 =======================================

重寫request的getSession方法實現叢集session共享

我們在用redis實現session共享的時候,會遇到這樣的問題:當一個使用者登陸後,可能叢集環境下給你分配到另一臺伺服器,這時候你用request.getSession()獲取的session是現在伺服器上的session,裡面沒有你想要的使用者資訊,然後你又要重新登入,這

使用Spring Session實現分散式的Session共享

之前在分散式環境下需要解決session共享的問題,更多的時候我們是使用servlet容器例如tomcat提供的叢集配置來解決session的複製問題。今天介紹一種簡單的解決方案。 1 1. 新增依賴 <dependency> <gro