分布式Session

一、Session

1.1 概述

  • Session:在计算机中,尤其是在网络应用中,称为“会话控制”。它是一种记录客户状态的机制,客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。
  • Session 对象存储特定用户会话所需的属性及配置信息。
  • 当用户在应用程序的Web页之间跳转时,存储在Session对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。

1.2 使用原理

二、分布式 Session

2.1 分布式 Session 问题

2.2 解决方案

2.2.1 方案一:session同步

  • 优点web-serverTomcat)提供原生支持,只需要修改配置文件。

  • 缺点

    • session 需要同步数据传输,会占用大量网络带宽,降低了服务器群的业务处理能力。
    • 任意一台web-server保存的数据都是所有web-serversession总和,会受到内存限制无法水平拓展更多的web-server
    • 大型分布式集群情况下,所有web-server都全量保存数据,则该方案不可取
  • 示意图

2.2.2 方案二:客户端存储

  • 优点:服务器不需要存储session,用户保存自己的session信息到cookie中,节省服务端资源。
  • 缺点
    • 每次http请求,携带用户在cookie中的完整信息,浪费网络带宽。
    • session数据存在cookie中,cookie有长度限制,并不能保存大量信息。
    • 存在泄露、篡改、窃取等安全隐患,则该方式不会使用
  • 示意图

2.2.3 方案三:hash一致性

  • 优点
    • 只需要修改nginx配置,不需要修改应用代码
    • 负载均衡:只要hash属性的值分布是均匀的,多台web-server的负载也同样是均衡的。
    • 可以支持web-server水平拓展
  • 缺点
    • session还是存在web-server中,所以web-server重启或者扩容后可能导致部分session丢失,影响到当前业务。
    • 若想进行水平拓展,rehashsession会重新分布,则会有一部分用户路由不到正确的session
  • 说明:因为session本来都是有时效的,所以以上缺点问题也不是很大。这两种反向代理方式都是可以使用的。
  • 示意图

2.2.4 方案四:后端统一存储

  • 优点
    • 没有安全隐患
    • 可以水平拓展,在数据库/缓存维度进行切分即可。
    • web-server重启或者扩容都不会session丢失
  • 缺点
    • 增加了一次网络调用。
    • 需要修改应用代码,如:将getSession()方法替换为从Redis查询数据的方式,由于该方式要去中间件服务获取数据,则要比通过读内存慢很多。
  • 说明:以上缺点可以使用SringSession完美解决。
  • 示意图

三、SpringSession

3.1 概述

  • Spring SessionSpring 家族中的一个子项目, 它提供一组 API 和实现, 用于管理用户的 session 信息。
  • 它把 servlet 容器实现的 httpSession 替换为 spring-session, 专注于解决 session 管理问题, session 信息存储在 Redis 中, 可简单快速且无缝的集成到我们的应用中。
  • 它有以下特性:
    • 提供用户session管理的API和实现。
    • 提供HttpSession,以中立的方式取代web容器的session,比如tomcat中的session
    • 支持集群session处理,不必绑定到具体的web容器去解决集群下的session共享问题。

3.2 整合

  • 步骤一:依赖引入
<!-- 整合 spring session 实现 session 共享-->
<dependency>
  <groupId>org.springframework.session</groupId>
  <artifactId>spring-session-data-redis</artifactId>
</dependency>
  • 步骤二:配置application.properties
# 指定存储类型
spring.session.store-type=redis
  • 步骤三:主启动类增加注解 @EnableRedisHttpSession
  • 步骤四:增加配置类
@Configuration
public class SessionConfig {
    
    @Bean
    public CookieSerializer cookieSerializer() {
        DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
        // 放大作用域
        cookieSerializer.setDomainName("父级域名");
        cookieSerializer.setCookieName("自定义cookie名");
        return cookieSerializer;
    }

    @Bean
    public RedisSerializer<Object> springSessionDefaultRedisSerializer() {
        return new GenericJackson2JsonRedisSerializer();
    }
    
}

3.3 核心原理

  • @EnableRedisHttpSession 导入 RedisHttpSessionConfiguration 配置

    • 给容器中添加了一个组件 RedisOperationsSessionRepositoryRedis操作session的增删改查封装类;
    • 继承 SpringHttpSessionConfiguration 初始化了一个 SessionRepositoryFiltersession 存储过滤器);每个请求过来都必须经过 Filter 组件;创建的时候,自动从容器中获取到了 SessionRepository
  • SessionRepositoryFilter

    • 将原生的 HttpServletRequest / Response 包装成 SessionRepositoryRequestWrapper / ResponseWrapper;包装后的对象应用到了后面整个执行链;
    • 以后获取 request.getSession(); 都会调用 wrappedRequesr.getSession(); 从SessionRepository获取。
  • 说明:设计模式采用到了装饰者模式

  • 核心方法

3.4 官方文档

其他具体使用细节,参考官方文档:https://docs.spring.io/spring-session/docs/2.5.0/reference/html5/#samples

四、结束语


“-------怕什么真理无穷,进一寸有一寸的欢喜。”

微信公众号搜索:饺子泡牛奶

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值