您的位置:首页 > 数据库 > Redis

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

2018-03-03 19:44 656 查看
(一)背景:
1 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");
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: