原文地址:http://www.osheep.cn/1428.html
分布式集群部署是目前大多数中小型网站都在使用的一种轻部署模式;
集群部署直接面临的一个问题就是session不一致的问题,因为单节点部署的session直接存储在Web容器的缓存中,这种方式可以通过session复制的策略来共享session;但是不推荐;
有两种大家比较常用的配置方式来共享session,其原理都是依赖于统一的中间缓存服务器;
方案一:
基于Web容器配置,比如每个集群节点Tomcat,在context.xml中添加RedisManager的配置;
方案二:
使用Spring提供的session共享组件,基于Redis等缓存服务器自己管理session,优点是部署轻便,无需修改部署容器配置,自己能够灵活使用;
以下重点分析方案二的使用:
- 添加依赖
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
<version>1.2.0.RELEASE</version>
</dependency>
- spring-mvc.xml配置文件添加:
<!-- Redis 连接池 配置 -->
<bean id="redisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<!--<property name="maxActive" value="32"></property>-->
<property name="maxIdle" value="6"></property>
<!--<property name="maxWait" value="15000"></property>-->
<property name="minEvictableIdleTimeMillis" value="300000"></property>
<property name="numTestsPerEvictionRun" value="3"></property>
<property name="timeBetweenEvictionRunsMillis" value="60000"></property>
<!--<property name="whenExhaustedAction" value="1"></property>-->
</bean>
<!-- Redis 连接工厂 配置 -->
<bean id="redisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
destroy-method="destroy" >
<property name="poolConfig" ref="redisPoolConfig"></property>
<property name="hostName" value="${redis.hostName}"></property>
<property name="port" value="${redis.port}"></property>
<property name="password" value="${redis.password}"></property>
<property name="database" value="${redis.database}"></property>
<property name="timeout" value="${redis.timeout}"></property>
<property name="usePool" value="${redis.usePool}"></property>
</bean>
<!-- Spring Session 管理 -->
<bean class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration"/>
<!-- 让Spring Session不再执行config命令 -->
<util:constant static-field="org.springframework.session.data.redis.config.ConfigureRedisAction.NO_OP"/>
- web.xml添加
<!-- Spring 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>
<dispatcher>REQUEST</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
<!-- Spring Session Filter -->
这样就可以实现分布式Session了。
注意:
1. spring的这个配置文件一定要写在web.xml的部分,写在其他地方不行。
1. filter的名字必须是springSessionRepositoryFilter
1. 如果使用了shiro,web.xml中一定要把放在最前面,然后写shiro的Filter配置,再写spring-session的Filter配置。后面就是其他的编码和servlet配置了。