Session共享
由于nginx是随机分配请求,假设一个用户登录时访问网站登录时被分配到192.168.50.137:8080上,然后进行了登录操作,此时该服务器上就会有该用户登录的session信息,然后登陆后重定向到网站首页或个人中心时,此时如果被分配到192.168.50.139:8080上,那么这台服务器上没有该用户session信息,于是又会变成未登录状态,所以由于nginx的负载均衡会导致session共享的问题。
解决方案:
1、使用ip_hash(不推荐)
upstream tomcat_server{ ip_hash; server 10.1.11.***:8080; server 10.1.11.***:8080; }
2、session存在memcache或redis中(推荐使用)
以这种方式来同步session,把session抽取出来,放到内存级数据库里面,解决了session共享问题,同时读取速度也是非常之快。
使用步骤
1、添加spring-session-data-redis的依赖(需要添加spring与redis整合需要的jar)
<dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> <type>pom</type> <version>1.3.0.RELEASE</version> </dependency>
2.在spring配置文件添加redis的配置以及spring-session的配置(在applicationContext-redis.xml 后添加)
<bean id="redisHttpSessionConfiguration" class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration"> <!-- 设置session存活时间 --> <property name="maxInactiveIntervalInSeconds" value="300000"></property> </bean>
3.在web.xml文件配置一个web-session的过滤器(配置在所有过滤器的前面为第一个过滤器,启动自动执行将session加入到redis中)
<!-- Spring session --> <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>
注意:
在启动服务的时候可能会出现TaskScheduler/ScheduledExecutorService的异常打印了出来。但是系统并没有受影响
正常使用,我们可以忽略这个错误,
但是如果你是一个处女座,看到异常不爽,那你可以在spring的配置文件加一个Bean,就可以解决上面的问题,配置如下:
<bean class="org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler"></bean>
测试:
1、启动redis服务器,哨兵
2、启动nginx
//配置一个虚拟主机集群 upstream tomcat_server{ server 10.1.11.**:8080; server 10.1.11.**:8080; } server { listen 80; server_name localhost; location / { proxy_pass http://tomcat_server/项目名/; } }
出现问题session失效:如果在nginx配置文件中添加了项目名
每请求一次,会创建一个新的session,把新的session存到了redis中,原因配置的是代理tomcat而不是代理项目
解决方案:将nginx中的请求路径去除项目名
location / { proxy_pass http://tomcat_server/; }