一、session是什么
存放在服务器内存中的数据,比如一个map。
二、分布式下session共享问题
2.1.1 不同域名间session不共享
2.1.2 同域名不同服务器间session不共享
解决方案:
(1)session复制
优点:tomcat原生支持,只需要修改配置文件。
缺点:数据传输占用大量带宽;任意一台tomcat保存的数据都是所有tomcat的session综合,占大量内存;不支持水平扩展;
(2)客户端存储
优点:用户保存自己的session信息到cookie中,节省服务器资源。
缺点:每次请求携带cookie,浪费带宽;cookie长度限制4k;cookie中信息存在泄露、篡改、窃取等安全隐患;
(3)hash一致性
优点:只需要改nginx配置,不需要改代码;只要hash属性的值分布是均匀的,多台tomcat的负载就是均衡的;可支持tomcat水平扩展;
缺点:服务器重启,session会丢失;tomcat水平扩展后,rehash后的session重新分布,一部分用户路由不到正确的session;
(4)统一存储
优点:没安全隐患;可水平扩展;服务器重启session不会丢失;
缺点:增加网络调用,需要修改代码;上面缺点可以用SpringSession解决;
(5)不同服务,子域的session共享
原理:放大域名的作用域(Domain)
三、SpringBoot整合SpringSession
3.1.1 引入依赖
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
3.1.2 修改配置文件
spring:
redis:
host: <ip>
port: 6379
session:
store-type: redis
3.1.3 编写配置类
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.session.web.http.CookieSerializer;
import org.springframework.session.web.http.DefaultCookieSerializer;
@Configuration
public class MySessionConfig {
@Bean
public CookieSerializer cookieSerializer() {
DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
//放大作用域
cookieSerializer.setDomainName("父域");
cookieSerializer.setCookieName("SESSION名");
return cookieSerializer;
}
@Bean
public RedisSerializer<Object> springSessionDefaultRedisSerializer() {
return new GenericJackson2JsonRedisSerializer();
}
}
3.1.4 主启动类开启session注解
@EnableRedisHttpSession