1、简述
传统单机web应用中,一般使用tomcat/jetty等web容器时,用户的session都是由容器管理。浏览器使用cookie中记录sessionId,容器根据sessionId判断用户是否存在会话session。这里的限制是,session存储在web容器中,被单台服务器容器管理。
2、Session复制
原生tomcat/jetty等web-server容器已支持,只需要修改配置即可。
缺点:session同步会占用大量的带宽,每台服务器要保留其他服务器数据。会受服务器内存限制影响。在集群环境,该方案不可取。
3、浏览器存储
将大量的session信息存储在浏览器cookie上,减少服务器内存。
缺点:每次http请求浪费网络带宽,而且如果有关键信息存储在cookie上,也会造成泄漏,引发安全性问题。cookie是有长度限制,所以不适合存储大量的session。
4、Nginx Hash一致性
通过Nginx中的ip_hash技术能够将某个ip 的请求定向到同一台后端web机器中,这样一来这个ip 下的客户端和某个后端 web机器就能建立起稳固的session,实现hash负载均衡。
缺点:session还是存储在web-server中,重启会造成session丢失。
session水平扩展时,rehash也会造成session丢失。
5、SpringSession
官网地址:https://spring.io/projects/spring-session
随着网站主键演变,分布式应用和集群是趋势(提高性能)。SpringSession孕育而生。简单描述原理:
当Web服务器接收到http请求后,当请求进入对应的Filter进行过滤,将原本需要由web服务器创建会话的过程转交给Spring-Session进行创建,本来创建的会话保存在Web服务器内存中,通过Spring-Session创建的会话信息可以保存第三方的服务中,如:redis,mysql等。Web服务器之间通过连接第三方服务来共享数据,实现Session共享!
5.1 核心
-
SessionRepository
SessionRepository是Spring Session的核心接口,定义了对会话数据的基本操作,如保存、删除和获取。Spring Session提供了多种SessionRepository的实现,可以选择适合自己场景的存储后端。 -
Session
Session接口代表一个用户会话,包含了会话的基本信息和操作方法。通过Session接口,可以获取和设置会话的属性,以及进行其他操作。 -
SessionRepositoryFilter
SessionRepositoryFilter是一个Servlet过滤器,用于将Session关联到Spring的SecurityContext中,确保会话在整个请求周期中得以正确使用。
5.2 存储
Spring Session支持多种存储后端,包括:
- 内存存储: 将会话数据保存在内存中,适用于单机环境或开发调试。
- JDBC存储: 通过关系数据库存储会话数据,支持跨应用、跨服务器。
- Redis存储: 使用Redis作为会话数据的存储介质,具有高性能和可扩展性。
以Redis session缓存为例,引入pom.xml
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
在配置中添加相关存储类型:
在application.properties指定Redis为session缓存容器。
spring.session.store-type=redis
server.servlet.session.timeout=30m
5.3 启动
添加启动器session注解@EnableRedisHttpSession
@EnableRedisHttpSession
@MapperScan("com.lm.shop.product.dao")
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients(basePackages = "com.lm.shop.product.feign")
public class ShopProductApplication {
public static void main(String[] args) {
SpringApplication.run(ShopProductApplication.class, args);
}
}
5.4 域名和序列化
- 多域名,子域名session共享问题
@Configuration
public class MySessionConfig {
@Bean
public CookieSerializer cookieSerializer(){
DefaultCookieSerializer defaultCookieSerializer = new DefaultCookieSerializer();
defaultCookieSerializer.setCookieName("LSKSESSION");
defaultCookieSerializer.setDomainName("lsk-ww.cn");
return defaultCookieSerializer;
}
}
- Redis session 存储Json格式转储
在MySessionConfig中添加转储Serializer
@Bean
public RedisSerializer<Object> redisSerializer(){
return new GenericFastJsonRedisSerializer();
}
6、优势
-
跨应用共享会话: Spring Session可以将会话数据存储在可共享的存储后端中,使得多个应用能够共享会话信息,实现单点登录等功能。
-
分布式环境下的会话管理: 适用于分布式部署的场景,通过外部存储后端,实现会话的统一管理。
-
灵活的存储选择: 支持多种存储后端,可以选择适合自己场景的存储方式,如内存、JDBC、Redis等。
7、小结
Spring Session为分布式环境下的会话管理提供了强大的解决方案。通过对核心概念的理解和简单的配置,可以在项目中轻松应用Spring Session,提升会话管理的效率和灵活性。在选择存储后端时,可以根据实际需求和系统特点进行灵活配置,以获得最佳性能和扩展性。