佛山企业网站建设平台,wordpress底部美化,wordpress archives页,电子商务网站建设与管理 李建忠Redisson 分布式锁
v1.0.0版本问题
v1.0.0版本的实现在持有锁的JVM或者持有锁的线程挂掉没有释放锁时#xff0c;该锁不会被释放并且会一直占用#xff0c;这个时候就使用DEL命令手动删除。
问题解决
v1.3.1版本通过key的ttl解决了这个问题#xff0c;关键加锁逻辑改为了…Redisson 分布式锁
v1.0.0版本问题
v1.0.0版本的实现在持有锁的JVM或者持有锁的线程挂掉没有释放锁时该锁不会被释放并且会一直占用这个时候就使用DEL命令手动删除。
问题解决
v1.3.1版本通过key的ttl解决了这个问题关键加锁逻辑改为了Lua脚本
加锁
,关键逻辑
根据key名称获取key的value数据如果value信息返回false则代表key不存在调用redis.call设置key和value并且设置key的超时时间为用户设置的时间或默认超时时间默认超时时间为30秒。如果value存在则json解码获取o字段o字段表示锁的owner)如果持有锁的JVM或线程是当前线程则将cc字段为JVM或线程持有锁/获等待锁的计数加1最后返回当前Key的TTL
local v redis.call(get, KEYS[1]);
if (v false) then redis.call(set, KEYS[1], cjson.encode({[o] ARGV[1], [c] 1}), px, ARGV[2]); return nil;
else local o cjson.decode(v); if (o[o] ARGV[1]) then o[c] o[c] 1; redis.call(set, KEYS[1], cjson.encode(o), px, ARGV[2]); return nil; end;return redis.call(pttl, KEYS[1]);
end解锁
先检查锁Key是否存在不存在返回OK同时发布消息问题它想解锁而此时锁却不存在了这是不是有可能已经出事了锁KEY还存在就检查一下owner是不是自己如果是自己就将计数减1如果计数还不为0就为锁续期如果计数为0就删除锁KEY同时发布事件。
local v redis.call(get, KEYS[1]);
if (v false) then redis.call(publish, ARGV[4], ARGV[2]); return OK;
else local o cjson.decode(v); if (o[o] ARGV[1]) then o[c] o[c] - 1; if (o[c] 0) then redis.call(set, KEYS[1], cjson.encode(o), px, ARGV[3]);return FALSE;else redis.call(del, KEYS[1]); redis.call(publish, ARGV[4], ARGV[2]); return OK;end end; return nil;
endLua脚本返回’OK’,FALSE’和nil的区别
OK 表示成功解锁已经被成功解锁因为锁不存在或已经删除FALSE: 此次解锁成功 但是锁并没有被删除因为unlock的次数还不够nil: 当前线程并没有持有该锁你为什要解锁给你个异常让你尝尝
问题
高负载下锁无法续期该怎么办
不管它由它去系统容量预估不要让你的系统中的组件有那么大的压力突发情况下万一某些业务或请求真的出问题了及时告警业务部门该买单的就买单吧