Tomcat+Nginx+Redis实现分布式Session共享

最近在研究Nginx+Tomcat实现负载均衡,实验成功后发现了一个问题:用户登录成功后,总是会自动退出系统。经过判断,发现在负载均衡的情况下,每次操作访问后台都有可能访问不同的Tomcat服务器,因此就会判断当前登录用户的session无效而导致退出系统。
解决这种问题的一个比较简单的方法就是在nginx的配置文件与负载均衡相关的配置处加入ip hash,这样每次就会只访问一台Tomcat服务器而不会退出系统。但是这样也有一个问题,就是如果访问的服务器挂了,就无法继续访问系统了。
咨询了一下同事,才知道可以用Tomcat+Nginx+Redis实现共享session,这样做既能达到负载均衡的目的,也能保持用户登录后session持久性,可谓一石二鸟。
采用Tomcat+Nginx+Redis实现分布式session共享大致分为3步:
1、 修改web系统配置;
2、 修改web系统中所有读取或操作session的地方;
3、 配置Nginx服务器。
下面分别来讲解一下这三步的操作:
1、 修改web系统配置
修改web系统配置也分3步:
1) 引入Redis的Maven依赖

<!-- Jedis -->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>2.8.2</version>
</dependency>
<!-- Spring Data Redis -->
<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-redis</artifactId>
    <version>1.5.2.RELEASE</version>
</dependency>
<!-- Spring Session -->
<dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session</artifactId>
    <version>1.1.1.RELEASE</version>
</dependency>
<!-- Apache Commons Pool -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
    <version>2.4.2</version>
</dependency>

2) 配置Redis
A) redis.properties

#redis主机地址
redis_hostName=127.0.0.1
#端口号
redis_port=6379
#密码
redis_password=123456
#连接超时时间
redis_timeout=20000

B) 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:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="http://www.springframework.org/schema/beans    http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
    <!-- session设置 -->
    <!-- 
        maxInactiveIntervalInSeconds是设置session有效时间,以秒为单位,
        但实际上无论怎么设,session真实有效时间还是会比我们设置的稍微长一些 
    -->
    <bean class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">
        <property name="maxInactiveIntervalInSeconds" value="3600" />
    </bean>

    <!-- redis连接池 -->
    <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig" />

    <!-- redis连接工厂 -->
    <bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
        <property name="hostName" value="${redis_hostName}" />
        <property name="port" value="${redis_port}" />
        <property name="password" value="${redis_password}" />
        <property name="timeout" value="${redis_timeout}" />
        <property name="poolConfig" ref="poolConfig" />
    </bean>
</beans>

3) 配置web.xml
A) 在web.xml文件中要引入spring-redis.xml配置文件:

<context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring-redis.xml</param-value>
</context-param>

B) 同时,还要配置Filter

<!-- 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>
</filter-mapping>

通常情况下,如果有其他的过滤器,一般将Spring Session过滤器放到第一位。
2、 修改web系统中所有读取或操作session的地方;
1) 如登录过程中,需要将session放到内存中:

HttpSession session = request.getSession();
User user = userService.findByLogin(username, password);
if(null != user){
    //需要注意的是如果要往redis中存入对象,则需要将该对象序列化才能存入
    session.setAttribute("loginUser", JSON.toJSONString(user));
}

2) 在拦截器中获取session信息的代码:
String userString = request.getSession().getAttribute(“loginUser”).toString();
User user = JSON.parseObject(userString, User.class);
3、 配置Nginx服务器:
这里写图片描述
至此,全部配置完成。对系统进行访问测试,用户登录后不会再发生因为session无效而退出系统的情况,系统已经能正常访问。

发布了8 篇原创文章 · 获赞 3 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/huanongying123/article/details/77728019