一、分布式加鎖過程
RLock lock = redissonClient.getLock(REDISSON_DISTRIBUTE_KEY);
lock.lock();
wireshark抓包可以看見:
*6
$4
EVAL
$336
if (redis.call('exists', KEYS[1]) == 0) then redis.call('hset', KEYS[1], ARGV[2], 1); redis.call('pexpire', KEYS[1], ARGV[1]); return nil; end; if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then redis.call('hincrby', KEYS[1], ARGV[2], 1); redis.call('pexpire', KEYS[1], ARGV[1]); return nil; end; return redis.call('pttl', KEYS[1]);
$1
1
$30
cache.redisson.distribute.lock
$5
30000
$40
b56fb34c-e1b7-400f-a635-ad6881f75c7b:110
整理後,如下:

// 如果key不存在,則調用hashset去設定,并設定過期時間
if (redis.call('exists', cache.redisson.distribute.lock) == 0)
then redis.call('hset', cache.redisson.distribute.lock, b56fb34c-e1b7-400f-a635-ad6881f75c7b:110, 1);
redis.call('pexpire', cache.redisson.distribute.lock,30000);
return nil;
end;
//key已經存在的情況下,直接incrby,然後設定過期時間
if (redis.call('hexists', cache.redisson.distribute.lock, b56fb34c-e1b7-400f-a635-ad6881f75c7b:110) == 1) then
redis.call('hincrby', cache.redisson.distribute.lock, b56fb34c-e1b7-400f-a635-ad6881f75c7b:110, 1);
redis.call('pexpire', cache.redisson.distribute.lock, 30000);
return nil;
end;
return redis.call('pttl', cache.redisson.distribute.lock);
二、redisson 解鎖過程
整理後,腳本如下:
if (redis.call('hexists', cache.redisson.distribute.lock, e16193b0-e25c-4563-bc6e-19cc88d6112a:105) == 0) then
return nil;
end;
// -1操作
local counter = redis.call('hincrby', cache.redisson.distribute.lock, e16193b0-e25c-4563-bc6e-19cc88d6112a:105, -1);
if (counter > 0) then
// 延長過期時間
redis.call('pexpire', cache.redisson.distribute.lock, 30000);
return 0;
else
// 删除分布式鎖的key,釋出消息
redis.call('del', cache.redisson.distribute.lock);
redis.call('publish', redisson_lock__channel:{cache.redisson.distribute.lock}, 0);
return 1;
end;
return nil;
https://my.oschina.net/u/2369201/blog/1573730
三、續期原理
可參考:https://juejin.im/post/5d122f516fb9a07ed911d08c
驗證時,如下圖,在過了20s後,(程式在sleep),開始續期:
看看續期包的内容:
可以看到,續了30s。然後因為我們睡眠了1分鐘,是以接下來又觸發了續期: