SpringSession

分布式下Session共享问题解决方案

1、session复制

优点: web-server(Tomcat) 原生支持,只需修改配置文件

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

2、客户端存储

优点:服务器不需要存储session,用户保存自己的session信息到cookie中。节省服务端资源

缺点:都是缺点,这只是一种思路。具体如下

每次http请求,携带用户在cookie中的完整信息,浪费网络带宽;cookie有长度限制4k,不能保存大量信息;session数据放在cookie中,存在泄露、篡改、窃取等安全隐患,这种方式不会使用

3、hash一致性

根据用户的IP进行判断,只要客户端的ip不变或者hash值取值不变,就会一直访问同一台服务器。

优点:只需要修改nginx配置,不需要修改应用代码;负载均衡,只要hash属性的值分布是均匀的,多台web-server的负载是均衡的;可以支持web-server水平拓展(session同步法是不行的,受内存限制)

缺点:session还是存在web-server中,所以web-server重启可能导致部分session丢失,影响业务,如部分用户需要重新登录;如果web-server水平扩展,rehash后session重新分布,也会有一部分用户路由不到正确的session

但是以上的缺点问题也不是很大,因为session本来都是有有效期的。所以这两种反向代理的方式可以使用

4、统一存储

由后端统一存储session,使用DB/Redis

优点:没有安全隐患;可以水平扩展,数据库/缓存水平切分即可;web-server重启或者扩容都不会有session丢失

缺点:增加了一次网络调用,并且需要修改应用代码;如将所有的getSession方法替换为从Redis查数据的方式。redis获取数据比直接从内存获取慢很多

上面的缺点可以用SpringSession完美解决

5、SpringSession

配置:存储类型:spring.session.store-type=redis

超时时间:server.servlet.session.timeout=30m

@EnableRedisHttpSession标在主类上

默认发的令牌作用域是当前域:需要解决子域共享问题,及应使用json的序列化方式序列化数据

@Configuration
public class GulimallSessionConfig {

    @Bean
    public CookieSerializer cookieSerializer() {

        DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();

        //放大作用域
        cookieSerializer.setDomainName("gulimall.com");
        cookieSerializer.setCookieName("GULISESSION");

        return cookieSerializer;
    }


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

}
posted @ 2022-01-11 13:31  阿伦啊  阅读(532)  评论(0编辑  收藏  举报