【集群部署】redis解决session共享问题

场景:在项目集群部署的时候遇到的一个坑,Nginx+Tomcat集群后发现,登陆总是登陆不上,亦或者是登陆上了一次,下一次请求又回到了登陆页,造成根本无法正常操作。在查询原因后发现了问题所在。 第一次请求被nginx分配到了Tomcat1,这时Session存在了Tomcat1,第二次请求却被分配到了Tomcat2。Tomcat2并没有已登录的Session,因此跳回了登录页,如此循环。。因此就需要在多台server之间共享session。

session共享的方法有很多,有tomcat自带的session共享,ehcache的集群同步,memcached,12306用的gemfire(这个以后有机会在研究吧哈哈)等等,这里我用redis的两种形式来实现session共享。

第一种:Tomcat可以依赖redis的lib包来实现共享, 这是比较简单的。
Step1:将三个redis相关jar包放入tomcat7的lib中。
三个jar包由Tomcat-redis-session-manager打包生成
注意:jar包不通用。tomcat8需要重新打包,代码有些变化。
Step2:修改tomcat配置文件context.xml
Context标签中新增如下配置,主机地址、端口以及密码等自行配置
<Valve className="com.radiadesign.catalina.session.RedisSessionHandlerValve" />  
	<Manager className="com.radiadesign.catalina.session.RedisSessionManager"  
         host="192.168.1.137"  
         port="6379"  
	 password="123456"		 
         database="0"   
         maxInactiveInterval="60"/>
Step3:启动tomcat、开启集群就行了。。

这是比较简单的session共享,但是每个tomcat都需要加入lib以及修改配置文件。这样集群的时候比较繁琐、那么继续往下看。

第二种:利用spring-session-data-redis
Step1:pom加入依赖:
<!-- spring session redis begin -->
        <dependency>
			<groupId>org.springframework.session</groupId>
			<artifactId>spring-session-data-redis</artifactId>
			<version>1.2.1.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>redis.clients</groupId>
			<artifactId>jedis</artifactId>
			<version>2.8.1</version>
		</dependency>
 <!-- spring session redis  end --> 
Step2:修改spring-mvc.xml配置,主机地址、端口以及密码自行配置
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
	<property name="maxTotal" value="30" />
	<property name="maxIdle" value="10" />
	<property name="minIdle" value="1" />
	<property name="maxWaitMillis" value="30000" />
	<property name="testOnBorrow" value="true" />
	<property name="testOnReturn" value="false" />
	<property name="testWhileIdle" value="false" />
</bean>

<bean id="redisHttpSessionConfiguration" 
class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">
        <property name="maxInactiveIntervalInSeconds" value="600" />
</bean> 

<bean id="jedisConnectionFactory"
	class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
	destroy-method="destroy">
	<property name="hostName" value="192.168.1.137" />
	<property name="port" value="6379" />
	<property name="password" value="123456" />
	<property name="timeout" value="3000" />
	<property name="usePool" value="true" />
	<property name="poolConfig" ref="jedisPoolConfig" />
</bean>
项目中还有用到redis可加入:
	<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
		<property name="connectionFactory" ref="jedisConnectionFactory" />
	</bean>
Step3:web.xml加入拦截器
<!-- Spring Session过滤器 begin -->
	<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>
<!-- Spring Session过滤器 end -->
至此配置完成。通过spring-session存储到redis中,项目部署也方便很多。
本文中很多也是借鉴了网上前辈的经验,再结合自身项目实际需求舍取,大家也可以根据自身项目的场景应用。请多指教,欢迎留言。

阅读更多
换一批

没有更多推荐了,返回首页