一次redis悲观锁 实现 微信jssdk token缓存

(一)背景:

access_token是公众号的全局唯一票据,公众号调用各接口时都需使用access_token,且每天有额度配额,最大调用次数限制

这一条决定:必须将access_token 缓存起来,否则每天都超标返回null


2 正常情况下access_token有效期为7200秒重复获取将导致上次获取的access_token失效

这一条决定:

(1)我们应将access_token 缓存7000秒,使用redis指定缓存时间是最好不过的

(2)先来看一下一般缓存代码:

        String token = (String)stringRedisTemplate.opsForValue().get(ACCESS);

        if(token == null) {
            token = WeXinCodeUtils.getAccessToken();
            stringRedisTemplate.opsForValue().set(ACCESS, token);
            System.out.println("request");
        } else {
            System.out.println("cache");
        }

先读后写,单线程下没有问题,输出:

request
cache

单在多线程下会有问题,而且会导致事故,比如:


B线程的请求token会导致A线程请求的token失效,A线程拿着失效的token,就失败了

对于这样的场景,我们都会想到两种方案:

1.悲观锁


这个方案可行,有点像单例模式,但是不应用于集群,同样会出事故:


synchronized不受多应用限制,导致应用A的token失效


故可以将synchronized替换为redis分布式锁


2.乐观锁


B线程请求token那会儿,A线程的token已经失效了,不管你乐观锁会报错,请求可不是数据库还给你token回滚,所以乐观锁在这个地方不适用,


故只能考虑分布式锁,有点像处理缓存击穿,这里是大并发场景,则是防大量请求同时爆到微信服务器,导致当日服务超次数限制。



(二)实现

1. 实现过程中,实践证明“正常情况下access_token有效期为7200秒重复获取将导致上次获取的access_token失效。“不准确,

重复获取不会导致上次获取的access_token失效,获取后7200秒自然失效

2. 本实例也不存在超高并发导致一秒内请求微信超限;


此2点决定:此次代码不考虑并发同步问题,一般代码处理即可,即:

一般缓存代码:

        String token = (String)stringRedisTemplate.opsForValue().get(ACCESS);

        if(token == null) {
            token = WeXinCodeUtils.getAccessToken();
            stringRedisTemplate.opsForValue().set(ACCESS, token);
            System.out.println("request");
        } else {
            System.out.println("cache");
        }



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值