Spring Boot系列十二 通过redis实现Tomcat集群的Session同步及从源码分析其原理

本文探讨如何在Spring Boot应用中利用Redis解决Tomcat集群的Session同步问题。通过创建Demo工程,详细介绍了配置Redis存储Session的步骤,并从源码层面解析其实现原理,包括ExpiringSessionHttpSession、SessionRepository、HttpSessionWrapper、SessionRepositoryRequestWrapper和SessionRepositoryFilter等关键类的作用。
摘要由CSDN通过智能技术生成

1. 概述

在tomcat等web容器中,session是保存在本机内存中。如果我们对tomcat做集群,不可避免要涉及到session同步的问题,必须保证同一个集群中的tomcat的session是共享的。本文通过Spring boot实现分布式系统Session同步,主要包括如下内容:

  • 详细介绍demo实现
  • 从源码的角度分析其实现原理

2. 多个tocmat的Session的管理。

在tomcat等web容器中,session是保存在本机内存中。如果我们对tomcat做集群,不可避免要涉及到session同步的问题,必须保证同一个集群中的tomcat的session是共享的。
为了tomcat集群正常的工作,通常有以下的方法:

a. 在tomcat的前端配置nginx等,采用ip_hash负载均衡算法,保证来自同一个IP的访客固定访问一个后端服务器,这样避免多个tomcat需要session同步的问题。这个方法也有缺陷,如果这台服务停机了,则所有的用户状态都丢失了
b. 通过tomcat自带的cluster方式,多个tomcat之间实时共享session信息,但是此方法随着tomcat数量和请求量增加性能会下降的比较厉害
c. 利用filter方法
d. 利用terracotta服务器共享session
e. 利用redis、memcached等中间件存储session

下文演示在spring boot中使用redis实现session的共享

3. spring boot中使用redis实现session的共享

3.1. Demo工程介绍

工程名称: redis
引入依赖jar

<!-- spring 引入 session 信息存储到redis里的依赖包  -->
<dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session-data-redis</artifactId>
</dependency>

application-dev.properties的session相关配置参数

### session的配置 start ############
# session的存储方式的类型配置
spring.session.store-type=redis
#spring.session.redis.namespace=
# session 存活时间
server.session.timeout=300
### session的配置 end ############

测试类SessionTestCtrl
在SessionTestCtrl.java中,我们会发现在配置redis共享后对session的操作和默认的session操作没有任何区别,其原理我们在下文的原理里再说。
此类有3个方法:
login(): 模拟登陆,在session中存储一个值

@RequestMapping("login")
public Map<String,Object> login(HttpServletRequest request) {
    HttpSession httpSession = request.getSession();
    // 设置session中的值
    httpSession.setAttribute("username", "hry" + System.currentTimeMillis());

    Map<String,Object> rtnMap = new HashMap<>();
    Enumeration<String> attributeNames = request.getSession().getAttributeNames();
    while(attributeNames.hasMoreElements()){
        String name = attributeNames.nextElement();
        rtnMap.put(name, httpSession.getAttribute(name));
    }
    rtnMap.put("sessionId", httpSession.getId());
    return rtnMap;
}

getSession(): 从session中获取值

@RequestMapping("get-session")
public Object getSession(HttpServletRequest request) {
    HttpSession httpSession = request.getSession();
    Map<String,Obje
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值