Redis SpringSession+Redis实现分布式Session存储

本文介绍如何在负载均衡环境中使用SpringSession结合Redis实现Session共享。通过在项目中引入必要的依赖并配置过滤器和Redis连接,使得Session数据能够统一存储在Redis中,从而解决集群环境下的Session共享问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用Spring Session的原因

在单台Tomcat应用中,通常使用session保存用户的会话数据。

在负载均衡的集群环境下,负载均衡可能将请求分发到不同的服务器上去,在这种情况,需要将有状态的session统一管理起来。

实现Session共享的方案很多,其中一种常用的就是使用Tomcat、Jetty等服务器提供的Session共享功能,将Session的内容统一存储在一个数据库(如MySQL)或缓存(如Redis)中.

本文主要介绍另一种实现Session共享的方案,不依赖于Servlet容器,而是Web应用代码层面的实现,直接在已有项目基础上加入spring Session框架,利用Redis集群做主从复制,利用redis数据库的最终一致性,将session信息存入redis中。

当应用服务器发现session不在本机内存的时候,就去redis数据库中查找,因为redis数据库是独立于应用服务器的数据库,所以可以做到session的共享和高可用。来实现Session统一存储在Redis中。

这里写图片描述

具体实现

首先导入项目依赖的jar包

<!-- 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>

在web.xml中配置Filter: 过滤器使HttpSession不再发挥作用,而是通过过滤器使用redis直接操作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>

redis配置文件redis.properties:

#redis config
redis.pool.maxTotal=105
redis.pool.maxIdle=10
redis.pool.maxWaitMillis=5000
redis.pool.testOnBorrow=true

#redis 单节点配置
redis.ip=127.0.0.1
redis.port=6379

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"
       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">

    <!-- 引入redis配置 -->
    <context:property-placeholder location="classpath:redis.properties" ignore-unresolvable="true"/>

    <!-- Redis 配置 -->
    <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <property name="maxTotal" value="${redis.pool.maxTotal}" />
        <property name="maxIdle" value="${redis.pool.maxIdle}" />
        <property name="maxWaitMillis" value="${redis.pool.maxWaitMillis}" />
        <property name="testOnBorrow" value="${redis.pool.testOnBorrow}" />
    </bean>

    <bean class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration"/>

    <!-- redis单节点数据库连接配置 -->
    <bean class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
        <property name="hostName" value="${redis.ip}" />
        <property name="port" value="${redis.port}" />
        <property name="poolConfig" ref="jedisPoolConfig" />
    </bean>

</beans>

可以测试一下功能

/**
 * Package: com.hqq.web
 * User: 何芊芊
 * Email: heqianqian1@jd.com
 * Date: 2017/11/6
 * Time: 18:01
 * Description:
 */
@Controller
public class IndexController {


    @RequestMapping("/index")
    public String index() {
        return "home";
    }


    @RequestMapping("/main")
    public String main(HttpServletRequest request) {
        HttpSession session = request.getSession();
        //从服务器获取session username
        String username = (String) session.getAttribute("username");
        //如果sessionId存在 用户登录过 就直接登录主页
        if (null != username) {
            return "main";
        } else {
            return "login";
        }
    }

    @RequestMapping(value = "/dologin")
    public String login(HttpServletRequest request) {
        HttpSession session = request.getSession();
        String username = request.getParameter("userInput");
        session.setAttribute("username", username);
        return "redirect:/main";
    }

    @RequestMapping(path = {"/login"}, method = {RequestMethod.GET})
    public String login() {
        return "login";
    }
}

访问之后查看redis数据库

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值