当前位置: 首页 > news >正文

【黑马点评】Redis解决集群的session共享问题

由于不同的tomcat服务器之间的session是不共享的,当请求如果在不同tomcat服务器之间切换就会导致数据丢失的问题。
在这里插入图片描述

使用redis可以解决session数据共享的问题
redis是tomcat以外的存储,存在redis中的数据,任何一台tomcat都能看得见,且redis是基于内存存储,又是k、v结构的存储方式。

redis保存登录用户信息时value的选择

在保存登录的用户信息时,

  1. 可以使用String结构,以json字符串来保存(比较直观、但是占用空间大):
    在这里插入图片描述
  2. 可以使用hash结构将对象中每个字段独立存储(对单个字段做CRUD、占用空间小):
    在这里插入图片描述

简单的数据类型(验证码),可以用string作为value存储
复杂的数据类型(对象),可以用hash作为value存储

UserDTO userDTO = BeanUtil.copyProperties(user, UserDTO.class); // 将User对象转成Hash存储
String tokenKey = RedisConstants.LOGIN_USER_KEY + token;
Map<String, Object> userMap = BeanUtil.beanToMap(userDTO, new HashMap<>(),
         CopyOptions.create().setIgnoreNullValue(true) // 忽略空值
                 .setFieldValueEditor((filedName, filedValue)-> String.valueOf(filedValue))); // 自己设置字段名和字段值
stringRedisTemplate.opsForHash().putAll(tokenKey, userMap);
stringRedisTemplate.expire(tokenKey, RedisConstants.LOGIN_USER_TTL, TimeUnit.MINUTES); // 设置30分钟有效期

redis保存用户信息时设置有效期问题

在redis中保存用户信息时,一定要给当前用户设置一个30分钟有效期,这样也可以避免数据在redis中占用过多的内存。但是注意:并不是用户登录后过了30分钟就直接得让他重新登录。应该是:用户登录后,如果还有访问系统,应该重新更新一遍有效期为30分钟。这就需要在登录拦截器中进行不断更新有效期

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 1. 获取请求头中的token
        String token = request.getHeader("Authorization");
        if(StrUtil.isBlank(token)){
            response.setStatus(401);
            return false;
        }
        // 2. 获取Redis中的用户
        String tokenKey = RedisConstants.LOGIN_USER_KEY + token;
        Map<Object, Object> userMap = stringRedisTemplate.opsForHash().entries(tokenKey);
        // 3. 判断用户是否存在
        if(userMap.isEmpty()){
            response.setStatus(401);
            return false;
        }
        UserDTO userDTO = BeanUtil.fillBeanWithMap(userMap, new UserDTO(), false);
        // 4. 保存用户信息到ThreadLocal
        UserHolder.saveUser(BeanUtil.copyProperties(userDTO, UserDTO.class));
        // 5. 刷新token有效期
        stringRedisTemplate.expire(tokenKey, RedisConstants.CACHE_SHOP_TTL, TimeUnit.SECONDS);
        return true;
    }

在实际开发的时候,我们可以设置两个拦截器:

  • 一个拦截器拦截所有请求,刷新token的有效期;
  • 一个拦截器拦截部分请求,判断ThreadLocal中是否存在用户
    在这里插入图片描述
http://www.dtcms.com/a/99135.html

相关文章:

  • wait函数等待多个子进程
  • vue3对比vue2新增特性
  • CSS 边框(Border)样式详解
  • 泛目录优化:无极泛目录优化网站,技术解析与风险控制指南
  • Flutter开发There are multiple heroes that share the same tag within a subtree报错
  • C++ explicit
  • 使用Java操作Redis
  • 在 Windows 中查看 Nginx 当前占用的端口
  • 基于高德地图实现地图交互功能的探索与总结
  • 函数式组件中的渲染函数 JSX
  • Python基础教程:从格式化到项目管理
  • QT操作PDF文件
  • 计算机视觉准备八股中
  • 多任务眼底血管与眼底血管中心线提取
  • Oracle数据库数据编程SQL<3.1 PL/SQL 匿名块 及 流程控制中的条件判断、循环、异常处理和随机函数应用>
  • CSS 美化页面(一)
  • 【Ai插件开发】Notepad++ AI插件开发进阶:集成Ai模型问答功能与流式交互实现
  • 【区块链安全 | 第九篇】基于Heimdall设计的智能合约反编译项目
  • SpringCould微服务架构之Docker(5)
  • [笔记.AI]初始向量
  • python基础学习二(列表及字典的使用)
  • 分布式ID服务实现全面解析
  • 【UE5.3.2】初学1:适合初学者的入门路线图和建议
  • 基于医疗大数据的肿瘤疾病模式分析与研究
  • MySQL 的 SQL 语句执行顺序
  • C++实现布隆过滤器
  • Linux--进程地址空间
  • Java基础关键_032_反射(二)
  • 六十天前端强化训练之第三十四天之CI/CD 大师级深度解析
  • CNN+Transformer+SE注意力机制多分类模型 + SHAP特征重要性分析,pytorch框架