• 【大型电商项目开发】分布式session原理,SpringBoot整合SpringSession-52


    一:session问题

    session底层就是服务器的一片内存空间,相当于map
    在这里插入图片描述

    • 1.不能跨域名进行共享
    • 2.同一个服务,复制多份,session不同步问题

    二:session共享问题解决

    1.session复制(不采用)

    优点:

    • web-server(Tomcat)原生支持,只需要修改配置文件

    缺点:

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

    2.客户端存储(不采用)

    优点:

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

    缺点:都是缺点,这只是一种思路。

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

    3.hash一致性

    在这里插入图片描述
    在这里插入图片描述
    优点:
    • 只需要改nginx配置,不需要修改应用代码
    • 负载均衡,只要hash属性的值分布是均匀的,多台 web-server的负载是均衡的
    • 可以支持web-server水平扩展(session同步法是不行 的,受内存限制)
    缺点:
    • session还是存在web-server中的,所以web-server重 启可能导致部分session丢失,影响业务,如部分用户 需要重新登录
    • 如果web-server水平扩展,rehash后session重新分布, 也会有一部分用户路由不到正确的session
    • 但是以上缺点问题也不是很大,因为session本来都是有有 效期的。所以这两种反向代理的方式可以使用

    4.统一存储(推荐)

    在这里插入图片描述
    优点:
    • 没有安全隐患
    • 可以水平扩展,数据库/缓存水平切分即 可
    • web-server重启或者扩容都不会有 session丢失

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

    三:SpringBoot整合SpringSession——完成session共享

    1.引入依赖

    <!--引入springSession-->
            
                org.springframework.session
                spring-session-data-redis
            
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2.配置文件配置session类型

    #redis的连接信息
    spring.redis.host127.0.0.1
    spring.redis.port=6389
    #session的类型
    spring.session.store-type=redis
    #session的过期时间
    server.servlet.session.timeout=30m
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    3.在主启动类添加@EnableRedisHttpSession

    //整合redis作为session存储
    @EnableRedisHttpSession
    
    • 1
    • 2

    四:子域session共享问题

    1.新建GulimailSessionConfig配置类

    @Configuration
    public class GulimailSessionConfig {
        @Bean
        public CookieSerializer cookieSerializer(){
            DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
            //指定作用域
            cookieSerializer.setDomainName("");
            //设定cookie名字
            cookieSerializer.setCookieName("GULISESSION");
            return cookieSerializer;
        }
        /**
         * 设置序列化机制
         * @return
         */
        @Bean
        public RedisSerializer<Object> springSessionDefaultRedisSerializer(){
            return new GenericJackson2JsonRedisSerializer();
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    五:SpringSession核心原理

    1.@EnableRedisHttpSession注解原理

    1)EnableRedisHttpSession导入了RedisHttpSessionConfiguration

    给容器中添加了组件

    • RedisOperationsSessionRepository,redis操作session的增删改查
    • SessionRepositoryFilter:session存储的过滤器,每个请求就需要经过过滤器。创建的时候就自动创建了。

    2.核心代码

    在这里插入图片描述

    • 放行包装之后的request和response应用到执行链。
    • 以后获取session:wrappedRequest.getSession()中获取
    • session会自动延期

    六:用户名密码登录整合session

    1.代码实现

    @PostMapping("/login")
        public String login(UserLoginVO vo, RedirectAttributes redirectAttributes, HttpSession session){
            //远程登录
            R r = memberFeignService.login(vo);
            if(r.getCode() == 0){
                //往session中去保存数据
                MemberRespVo data = r.getData(new TypeReference<MemberRespVo>(){});
                session.setAttribute(AuthServerConstant.LOGIN_USER,data);
                //成功就去首页
                return "redirect:http://127.0.0.1:10000";
            } else {
                Map<String, String> errors =new HashMap<>();
                errors.put("mag",r.getData(new TypeReference<String>(){}));
                redirectAttributes.addFlashAttribute("errors",errors);
                //失败就去登录页
                return "redirect:http://127.0.0.1:20000/login.html";
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    2.登录的时候先看session中有没有用户信息,如果有就不需要登录了。

  • 相关阅读:
    java 面向对象 day3
    03 【资源处理】
    生成动态指定条件的拼接SQL
    制造业数字化系统国产替代如何做?
    Makefile学习笔记
    C++官网 Information History of C++
    云原生爱好者周刊:电子书《可观测性工程》开放下载 | 2022-08-01
    flutter app和h5之间的通信
    基于51单片机简易十字路口交通灯_5s全黄闪烁
    【SpringBoot3+Vue3】四【基础篇】-前端(vue基础)
  • 原文地址:https://blog.csdn.net/suiyishiguang/article/details/126795796