基于redis的分布式锁解决token续期冲突的问题

news/2024/11/14 21:53:58/

场景:用户登录状态存储到redis,2小时后过期。在过期前的30分钟如果用户进行操作,则对登录状态进行续期,续期后仍有2小时时限,并更换新的token。在微服务模式下,如果两个服务同时请求续期,则会返回两个不同的token,其中一个是无效的,这会导致用户登出。加锁以避免这个问题。

java">    private final StringRedisTemplate redisTemplate;	private static final Long SUCCESS = 1L;/*** 锁的超时时间 10s*/private static final long TIMEOUT = 9999;/*** 加锁,无阻塞** @param* @param* @return*/public Boolean tryLock(String key, String value, long expireTime) {long start = System.currentTimeMillis();for (; ; ) {//SET命令返回OK ,则证明获取锁成功Boolean ret = redisTemplate.opsForValue().setIfAbsent(key, value, expireTime, TimeUnit.SECONDS);if (ret) {return true;}//防止执行过快try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}//否则循环等待,在timeout时间内仍未获取到锁,则获取失败long wait = System.currentTimeMillis() - start;if (wait >= TIMEOUT) {return false;}}}/*** 解锁(如果get(key)==value则删除key否则什么都不做)** @param* @param* @return*/public Boolean unlock(String key, String value) {String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";RedisScript<Long> redisScript = new DefaultRedisScript<>(script, Long.class);Long execute = redisTemplate.execute(redisScript, Collections.singletonList(key), value);if (SUCCESS.equals(execute)) {return true;}return false;}
java">    /*** 使用分布式锁续期token** @param response* @param userName 用户名 唯一* @param userDTO 业务参数* @param token* @param client 业务参数*/private void syncRenewalToken(HttpServletResponse response, String userName, UserDTO userDTO, String token, int client) {log.info(userDTO.getId() + " token续期");String uuid = UUID.randomUUID().toString().replaceAll("-", "");redisTemplate.tryLock("lock:" + userName, uuid, properties.getLockSurvive());//中间是对token进行续期的逻辑redisTemplate.unlock("lock:" + userName, uuid);}

http://www.ppmy.cn/news/1463494.html

相关文章

万博智云×华为云 | HyperBDR云容灾上架,开启联营联运新篇章

日前&#xff0c;万博智云HyperBDR云容灾正式入驻华为云云商店&#xff0c;成为华为云基础软件领域联营联运合作伙伴。通过联营联运&#xff0c;双方将进一步加深在产品、解决方案、渠道拓展等多方面的强强联合&#xff0c;为企业提供更加安全、高效的数据保护解决方案&#xf…

常见的JavaScript设计模式(一)

常见的JavaScript设计模式 一、模块模式(Module Pattern)二、单例模式&#xff08;SingIeton Pattern&#xff09;三、工厂模式&#xff08;Factory Pattern&#xff09;四、观察者模式&#xff08;Observer Pattern&#xff09; 常见的JavaScript设计模式包括 模块模式、 在…

添加AXI主IP(AXI4 Lite和AXI4)示例

添加AXI主IP&#xff08;AXI4 Lite和AXI4&#xff09;示例 将等效IP添加到框图中。以下是AXI Central的示例步骤 直接存储器存取&#xff08;CDMA&#xff09;&#xff1a; 1.右键单击方框图中的任意位置&#xff0c;然后选择“添加IP”。 2.搜索并双击AXI Central Direct Memo…

强化学习_06_pytorch-PPO2实践(Humanoid-v4)

一、PPO优化 PPO的简介和实践可以看笔者之前的文章 强化学习_06_pytorch-PPO实践(Pendulum-v1) 针对之前的PPO做了主要以下优化&#xff1a; -笔者-PPO笔者-PPO2refdata collectone episodeseveral episode(one batch)activationReLUTanhadv-compute-compute adv as one seri…

C-数据结构-树状存储基本概念

‘’’ 树状存储基本概念 深度&#xff08;层数&#xff09; 度&#xff08;子树个数&#xff09; 叶子 孩子 兄弟 堂兄弟 二叉树&#xff1a; 满二叉树&#xff1a; 完全二叉树&#xff1a; 存储&#xff1a;顺序&#xff0c;链式 树的遍历&#xff1a;按层遍历&#xff0…

springboot相关知识集锦----1

一、springboot是什么&#xff1f; springboot是一个用于构建基于spring框架的独立应用程序的框架。它采用自动配置的原则&#xff0c;以减少开发人员在搭建应用方面的时间和精力。同时提升系统的可维护性和可扩展性。 二、springboot的优点 约定优于配置 版本锁定&#xf…

【建议收藏】30个较难Python脚本,纯干货分享

本篇较难&#xff0c;建议优先学习上篇 &#xff1b;20个硬核Python脚本-CSDN博客 接上篇文章&#xff0c;对于Pyhon的学习&#xff0c;上篇学习的结束相信大家对于Pyhon有了一定的理解和经验&#xff0c;学习完上篇文章之后再研究研究剩下的30个脚本你将会有所成就&…

《AI学习笔记》大模型-微调/训练区别以及流程

阿丹&#xff1a; 之前一直对于大模型的微调和训练这两个名词不是很清晰&#xff0c;所有找了一个时间来弄明白到底有什么区别以及到底要怎么去使用去做。并且上手实践一下。 大模型业务全流程&#xff1a; 大模型为啥要微调&#xff1f;有哪些微调方式&#xff1f; 模型参数…