spring Session + Redis叢集 + 哨兵部署下實現Session共享
阿新 • • 發佈:2019-01-09
1.共享Session問題
最簡單的想法就是把session資料儲存到記憶體以外的一個統一的地方,例如Memcached/Redis等資料庫中。那麼問題又來了,如何替換掉Servlet容器建立和管理HttpSession的實現呢?
(1)設計一個Filter,利用HttpServletRequestWrapper,實現自己的 getSession()方法,接管建立和管理Session資料的工作。spring-session就是通過這樣的思路實現的。
(2)利用Servlet容器提供的外掛功能,自定義HttpSession的建立和管理策略,並通過配置的方式替換掉預設的策略。不過這種方式有個缺點,就是需要耦合Tomcat/Jetty等Servlet容器的程式碼。這方面其實早就有開源專案了,例如memcached-session-manager,以及tomcat-redis-session-manager。暫時都只支援Tomcat6/Tomcat7。
2.Spring Session介紹
Spring Session提供了一套建立和管理Servlet HttpSession的方案。Spring Session提供了叢集Session(Clustered Sessions)功能,預設採用外接的Redis來儲存Session資料,以此來解決Session共享的問題。
下面來一個demo展示一下我的實現方式
3.Maven依賴
<!-- Jedis --> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0</version> </dependency> <!-- Spring Data Redis --> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>1.7.3.RELEASE</version> </dependency> <!-- Spring Session --> <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session</artifactId> <version>1.2.2.RELEASE</version> </dependency> <!-- Apache Commons Pool --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> <version>2.4.2</version> </dependency>
4、配置filter
web.xml:
<!-- 分散式Session共享Filter --> <filter> <filter-name>springSessionRepositoryFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <filter-mapping> <filter-name>springSessionRepositoryFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
5、redis.properties
由於redis是多節點叢集哨兵配置,故此有三個連線ip
# Redis settings
redis.sentinels1=192.168.0.157
redis.sentinels2=192.168.0.160
redis.sentinels3=192.168.0.164
redis.sentinel.port=26379
#sentinel\u7684\u9274\u6743\u5bc6\u7801
redis.sentinel.masterName=mymaster
redis.sentinel.password=raymond
#\u6700\u5927\u95f2\u7f6e\u8fde\u63a5\u6570
redis.maxIdle=500
#\u6700\u5927\u8fde\u63a5\u6570\uff0c\u8d85\u8fc7\u6b64\u8fde\u63a5\u65f6\u64cd\u4f5credis\u4f1a\u62a5\u9519
redis.maxTotal=5000
redis.maxWaitTime=1000
redis.testOnBorrow=true
redis.testOnReturn=false
redis.testWhileIdle=false
#\u6700\u5c0f\u95f2\u7f6e\u8fde\u63a5\u6570\uff0cspring\u542f\u52a8\u7684\u65f6\u5019\u81ea\u52a8\u5efa\u7acb\u8be5\u6570\u76ee\u7684\u8fde\u63a5\u4f9b\u5e94\u7528\u7a0b\u5e8f\u4f7f\u7528\uff0c\u4e0d\u591f\u7684\u65f6\u5019\u4f1a\u7533\u8bf7\u3002
redis.minIdle=300
6、spring檔案配置
applicationContext.xml 裡面引入spring-redis.xml檔案
<import resource="classpath:spring-redis.xml" />
spring-redis.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p" xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
">
<!-- spring session -->
<bean id="redisHttpSessionConfiguration" class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">
<property name="maxInactiveIntervalInSeconds" value="1800"/>
</bean>
<!-- reids連線工廠配置 -->
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" destroy-method="destroy">
<constructor-arg name="sentinelConfig" ref="sentinelConfiguration"/>
<constructor-arg name="poolConfig" ref="poolConfig"/>
<property name="password" value="${redis.sentinel.password}"/>
</bean>
<!-- redis連線池配置 -->
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxTotal" value="${redis.maxTotal}" />
<property name="minIdle" value="${redis.minIdle}" />
<property name="maxWaitMillis" value="${redis.maxWaitTime}" />
<property name="maxIdle" value="${redis.maxIdle}" />
<property name="testOnBorrow" value="${redis.testOnBorrow}" />
<property name="testOnReturn" value="${redis.testOnReturn}" />
<property name="testWhileIdle" value="${redis.testWhileIdle}" />
</bean>
<!-- redis分散式 哨兵配置 -->
<bean id="sentinelConfiguration" class="org.springframework.data.redis.connection.RedisSentinelConfiguration">
<property name="master">
<bean class="org.springframework.data.redis.connection.RedisNode">
<property name="name" value="${redis.sentinel.masterName}"></property>
</bean>
</property>
<property name="sentinels">
<set>
<bean class="org.springframework.data.redis.connection.RedisNode">
<constructor-arg name="host" value="${redis.sentinels1}"></constructor-arg>
<constructor-arg name="port" value="${redis.sentinel.port}"></constructor-arg>
</bean>
<bean class="org.springframework.data.redis.connection.RedisNode">
<constructor-arg name="host" value="${redis.sentinels2}"></constructor-arg>
<constructor-arg name="port" value="${redis.sentinel.port}"></constructor-arg>
</bean>
<bean class="org.springframework.data.redis.connection.RedisNode">
<constructor-arg name="host" value="${redis.sentinels3}"></constructor-arg>
<constructor-arg name="port" value="${redis.sentinel.port}"></constructor-arg>
</bean>
</set>
</property>
</bean>
</beans>
注意:使用spring session有版本限制,這個版本問題坑壞我了,經過多次試驗,才把本公司專案session共享搞定,由於本公司專案沒有采用maven管理,故我把自己的jar包也發出來了,以供大家自行下載使用,地址:點選開啟連結