分布式系统下的Session使用

分布式系统下的Session使用

单体项目下Session的使用

用户通过浏览器访问服务器时,后台会根据当前的用户信息创建一个对应的session并保存在服务器的内存中,同时会通过一个JSESSIONID的cookie保存在用户的浏览器的cookie storage中,以后每次发送请求都会携带上它。

服务器就可以根据这个JSESSIONID来辨别当前是那个用户的会话

Tomcat的底层中,它是通过map的形式来进行session的保存

其中JSESSIONID对应cookie的domain是当前访问的请求的domain

迁移到分布式系统中存在的问题

问题一:

session只是保存在每台服务器的内存中,分布式项目中不同的服务部署在不同的机器上,那么session一定无法进行同步共享,因而如果采用轮询的负载均衡方式进行服务的请求将会导致session不共享而使得用户可能在当前会话期间重复的进行登录

问题二:

二级域名auth.gullmall.com下进行session保存到对应的cookiedomian是二级域名,那么如果从auth.guilmall.com跳转一级域名gulimall.com是无法获取到JSESSIONID的cookie

对应的解决方式

问题一的解决方式:

  1. 通过tomcat的底层配置,修改配置文件,让Session的信息在tomcat之间的复制。但是这个非常的不推荐,因为tomcat的数量越多则当前tomcat需要复制其他tomcat容器的session内容越大,这样在内存方面是不可能实现的
  2. 通过客户端包含会话信息的,这种是将当前用户与网站交互所需要的信息都包含在cookie中,每次进行请求的时候都携带上这些内容。这种方式也是几乎不可能实现的,因为请求头中header是存在4kb的限制的,超过这个限制则无法进行请求的发送,其次这也会带来安全问题,如果用户遭到浏览器的安全问题而导致这些cookie信息的暴露将会泄露用户的信息,进一步的将会导致用户在网站中资源的被盗取
  3. 通过ip_hash的方式,而不通过轮询的方式来,这个通过固定用户请求的服务器保证当前用户的session是保存在当前的服务器中。但是这样的可扩展性差,如果服务的机器数量进行扩容,则还需要重新ip_hash的计算,此外如果访问的途中,服务器进行重启或者其他将会导致session的丢失
  4. 第四种则是通过统一的session保存机制,也即session的存储可能是在MYSQL中或者redis中,不同的服务如果需要进行session的使用则从统一的session管理处获取即可,这样就进行session的统一管理。但是这样也存在问题,需要进行另外的配置,通过自定义的方式进行实现也非常的麻烦,但是很好的是,spring session可以来帮助我们完成这样的功能
USER
SERVICEA
REDIS-SESSION-STORE
SERVICEB
SERVICEC

问题二的解决方式:

原生的session进行JSESSIONID的存储的domain是使用默认的,而我们只需要在进行创建的时候进行修改即可,但是手动修改是非常的麻烦。但是恰好是,spring session提供我们自己配置的方式来修改domain来保证JSESSIONID的存储是通过一级域名的方式进行存储(cookie的domain域的自动访问是通过浏览器来进行的)

SpringSession的解决方案

介绍:是什么

Spring Session provides an API and implementations for managing a user’s session information.

特性:

Spring Session makes it trivial to support clustered sessions without being tied to an application container specific solution.


Spring Session使得可以进行集群的session支持而不去绑定指定的容器的解决方案

它还提供事务集成 transaction integration:

  • HttpSession - allows replacing the HttpSession in an application container (i.e. Tomcat) neutral way, with support for providing session IDs in headers to work with RESTful APIs(即:自定义HttpSession来进行session的管理)
  • WebSocket - provides the ability to keep the HttpSession alive when receiving WebSocket messages
  • WebSession - allows replacing the Spring WebFlux’s WebSession in an application container neutral way

使用Spring Session的三种方式

  1. Spring Session JDBC
  2. Spring Session Data Redis
  3. Spring Session Hazelcast

第一步:导入配置

  <!--spring session data redis:使用redis作为session方式-->
  <dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session-data-redis</artifactId>
  </dependency>
  <!--对应则需要进入redis的启动包-->
  <dependency>
  	<groupId>org.springframework.boot</groupId>
  	<artifactId>spring-boot-starter-data-redis</artifactId>
  </dependency>

第二步:编写配置

spring.session.store-type=redis # 指定redis作为session的存储方式

server.servlet.session.timeout= 指定session的过期时间,默认为秒
spring.session.redis.flush-mode=on_save # Sessions flush mode.
spring.session.redis.namespace=spring:session # 键的前缀名

第三步:1.自定义redis存储session的形式

//redis中存储session中的数据是通过jdk的序列化机制进行存储的,如果希望通过json的形式则需要注入RedisSerizlizer

@Bean
public RedisSerializer redisSerializer(){
	return xxx;//可以使用fastjson的序列化机制进行
}

第三步:2.自定义JSESSIONID的存储(解决子域cookie不共享的问题)

	//只需要注入CookieSerializer即可
	@Bean
	public CookieSerializer cookieSerializer() {
		DefaultCookieSerializer serializer = new DefaultCookieSerializer();
		serializer.setCookieName("JSESSIONID"); 
		serializer.setCookiePath("/"); 
		serializer.setDomain();//进行显式的将cookie的domain的作用域的修改
		serializer.setDomainNamePattern("^.+?\\.(\\w+\\.[a-z]+)$"); 
		return serializer;
	}

第四步:开启spring session redis

@EnableRedisSpringSession

第五步:使用

HttpSession session

我们只需要正常的调用,session.setAttribute()即可,底层默认会进行session的转换

Spring Session的核心原理(老版)

在这里插入图片描述

主要就是通过装饰器模式,包装原来的session为spring session

后续的filter执行链都将会获取到这个包装后的session,也即request.getSession()是经过重写的方法


RedisOperationSessionRepository:使用redis操作session的CURD操作类

SessionRepositoryFilter:存储过滤器,每个请求都必须经过的filter

说明:本文根据尚硅谷-谷粒商城来进行整理

est.getSession()`是经过重写的方法


RedisOperationSessionRepository:使用redis操作session的CURD操作类

SessionRepositoryFilter:存储过滤器,每个请求都必须经过的filter

说明:本文根据尚硅谷-谷粒商城来进行整理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值