有这样一个业务场景,窗口卖票,票的数量是一定的,很多人来抢票,如何才能使得票不会超卖呢,比如下面的代码是模拟卖票的场景
public class SellTicket implements Runnable {
private int tickets = 100;
@Override
public void run() {
while (tickets>0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在出售第"+tickets-- +"张票");
}
}
}
当启动三个线程表示窗口去卖票
public class SellTicketTest {
public static void main(String[] args) {
SellTicket st = new SellTicket();
for (int i = 1; i <= 3; i++) {
new Thread(st,"窗口"+i).start();
}
}
}
如果不加任何控制的话会出现超卖或者重复卖的情况
当然我们这里可以使用synchronized或者lock进行加锁,这样就不会出现超卖的情况,但是这种情况只适合单体架构,在分布式场景中是无法适用的,所以这时候就要使用分布式锁来实现了。
实现分布式锁有几种方式:
1、基于数据库的乐观锁或悲观锁
2、基于zookeeper
3、基于redis实现
本文探讨基于redis实现的分布式锁,利用的是setnx命令,setnx表示如果key存在,则无法写入,如下所示:
比如我们可以定义一个key,多个线程同时来抢,当拿到key之后,则进行后续的操作,操作完毕后再把key删除,这样相当于释放锁,当然这样肯定是有问题的,因为set跟del是两个操作,这样极有可能在执行del之前比如说服务器断电了,那么这把锁就无法释放了,还有假如程序要执行很久,也相当于一直持有锁了,所以我们要加上超时机制【setnx+expire】,并且这两个操作要具有原子性,也就是说加锁跟设置超时肯定同时执行或不执行,这个时候我们可以使用lua脚本进行操作,lua脚本天生就是原子性的。
开源框架redisson就是使用上述原理实现的分布式锁,首先引入pom文件
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.9.1</version>
</dependency>
然后在实现类调用redisson相关的api即可,也就是先创建好一把锁匙,当线程过来的时候谁先拿到锁匙谁就去执行业务代码,跟lock的用法很类似
public class SellTicket_redisson implements Runnable {
private int tickets = 100;
RLock lock = getRedissonLock();
private RLock getRedissonLock(){
Redisson redisson = (Redisson) Redisson.create();
RLock lock = redisson.getLock("keyLock");
return lock;
}
@Override
public void run() {
while (tickets>0){
lock.lock();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
System.out.println(Thread.currentThread().getName()+"正在出售第"+tickets-- +"张票");
}
}
}
从日志可以看出redisson本质也是在执行lua脚本
窗口2正在出售第2张票
22:09:27.623 [窗口2] DEBUG org.redisson.command.CommandAsyncService - acquired connection for command (EVAL) and params [if (redis.call('exists', KEYS[1]) == 0) then redis.call('publish', KEYS[2], ARGV[1]); return 1; end;if (redis.call('hexists', KEYS[1], ARGV[3]) == 0) then return nil;end; local counter = redis.call('hincrby', KEYS[1], ARGV[3], -1); if (counter > 0) then redis.call('pexpire', KEYS[1], ARGV[2]); return 0; else redis.call('del', KEYS[1]); redis.call('publish', KEYS[2], ARGV[1]); return 1; end; return nil;, 2, keyLock, redisson_lock__channel:{keyLock}, 0, 30000, b4af98de-c972-4bba-ae9b-73428bc0d0fa:22] from slot NodeSource [slot=null, addr=null, redisClient=null, redirect=null, entry=MasterSlaveEntry [masterEntry=[freeSubscribeConnectionsAmount=0, freeSubscribeConnectionsCounter=49, freeConnectionsAmount=31, freeConnectionsCounter=63, freezed=false, freezeReason=null, client=[addr=redis://127.0.0.1:6379], nodeType=MASTER, firstFail=0]]] using node 127.0.0.1/127.0.0.1:6379... RedisConnection@1164113667 [redisClient=[addr=redis://127.0.0.1:6379], channel=[id: 0x40e89550, L:/127.0.0.1:57766 - R:127.0.0.1/127.0.0.1:6379]]
22:09:27.623 [redisson-netty-1-3] DEBUG org.redisson.command.CommandAsyncService - connection released for command (EVAL) and params [if (redis.call('exists', KEYS[1]) == 0) then redis.call('publish', KEYS[2], ARGV[1]); return 1; end;if (redis.call('hexists', KEYS[1], ARGV[3]) == 0) then return nil;end; local counter = redis.call('hincrby', KEYS[1], ARGV[3], -1); if (counter > 0) then redis.call('pexpire', KEYS[1], ARGV[2]); return 0; else redis.call('del', KEYS[1]); redis.call('publish', KEYS[2], ARGV[1]); return 1; end; return nil;, 2, keyLock, redisson_lock__channel:{keyLock}, 0, 30000, b4af98de-c972-4bba-ae9b-73428bc0d0fa:22] from slot NodeSource [slot=null, addr=null, redisClient=null, redirect=null, entry=MasterSlaveEntry [masterEntry=[freeSubscribeConnectionsAmount=0, freeSubscribeConnectionsCounter=49, freeConnectionsAmount=32, freeConnectionsCounter=64, freezed=false, freezeReason=null, client=[addr=redis://127.0.0.1:6379], nodeType=MASTER, firstFail=0]]] using connection RedisConnection@1164113667 [redisClient=[addr=redis://127.0.0.1:6379], channel=[id: 0x40e89550, L:/127.0.0.1:57766 - R:127.0.0.1/127.0.0.1:6379]]
22:09:27.624 [窗口1] DEBUG org.redisson.command.CommandAsyncService - acquired connection for command (EVAL) and params [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, keyLock, 30000, b4af98de-c972-4bba-ae9b-73428bc0d0fa:21] from slot NodeSource [slot=null, addr=null, redisClient=null, redirect=null, entry=MasterSlaveEntry [masterEntry=[freeSubscribeConnectionsAmount=0, freeSubscribeConnectionsCounter=49, freeConnectionsAmount=30, freeConnectionsCounter=62, freezed=false, freezeReason=null, client=[addr=redis://127.0.0.1:6379], nodeType=MASTER, firstFail=0]]] using node 127.0.0.1/127.0.0.1:6379... RedisConnection@1704569104 [redisClient=[addr=redis://127.0.0.1:6379], channel=[id: 0x5b21c562, L:/127.0.0.1:57749 - R:127.0.0.1/127.0.0.1:6379]]
22:09:27.624 [窗口2] DEBUG org.redisson.command.CommandAsyncService - acquired connection for command (EVAL) and params [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, keyLock, 30000, b4af98de-c972-4bba-ae9b-73428bc0d0fa:22] from slot NodeSource [slot=null, addr=null, redisClient=null, redirect=null, entry=MasterSlaveEntry [masterEntry=[freeSubscribeConnectionsAmount=0, freeSubscribeConnectionsCounter=49, freeConnectionsAmount=30, freeConnectionsCounter=62, freezed=false, freezeReason=null, client=[addr=redis://127.0.0.1:6379], nodeType=MASTER, firstFail=0]]] using node 127.0.0.1/127.0.0.1:6379... RedisConnection@607817251 [redisClient=[addr=redis://127.0.0.1:6379], channel=[id: 0xbf8c408e, L:/127.0.0.1:57776 - R:127.0.0.1/127.0.0.1:6379]]
22:09:27.625 [redisson-netty-1-8] DEBUG org.redisson.command.CommandAsyncService - connection released for command (EVAL) and params [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, keyLock, 30000, b4af98de-c972-4bba-ae9b-73428bc0d0fa:21] from slot NodeSource [slot=null, addr=null, redisClient=null, redirect=null, entry=MasterSlaveEntry [masterEntry=[freeSubscribeConnectionsAmount=0, freeSubscribeConnectionsCounter=49, freeConnectionsAmount=31, freeConnectionsCounter=63, freezed=false, freezeReason=null, client=[addr=redis://127.0.0.1:6379], nodeType=MASTER, firstFail=0]]] using connection RedisConnection@1704569104 [redisClient=[addr=redis://127.0.0.1:6379], channel=[id: 0x5b21c562, L:/127.0.0.1:57749 - R:127.0.0.1/127.0.0.1:6379]]
22:09:27.625 [redisson-netty-1-2] DEBUG org.redisson.command.CommandAsyncService - connection released for command (EVAL) and params [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, keyLock, 30000, b4af98de-c972-4bba-ae9b-73428bc0d0fa:22] from slot NodeSource [slot=null, addr=null, redisClient=null, redirect=null, entry=MasterSlaveEntry [masterEntry=[freeSubscribeConnectionsAmount=0, freeSubscribeConnectionsCounter=49, freeConnectionsAmount=32, freeConnectionsCounter=64, freezed=false, freezeReason=null, client=[addr=redis://127.0.0.1:6379], nodeType=MASTER, firstFail=0]]] using connection RedisConnection@607817251 [redisClient=[addr=redis://127.0.0.1:6379], channel=[id: 0xbf8c408e, L:/127.0.0.1:57776 - R:127.0.0.1/127.0.0.1:6379]]
22:09:27.626 [窗口2] DEBUG org.redisson.command.CommandAsyncService - acquired connection for command (EVAL) and params [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, keyLock, 30000, b4af98de-c972-4bba-ae9b-73428bc0d0fa:22] from slot NodeSource [slot=null, addr=null, redisClient=null, redirect=null, entry=MasterSlaveEntry [masterEntry=[freeSubscribeConnectionsAmount=0, freeSubscribeConnectionsCounter=49, freeConnectionsAmount=31, freeConnectionsCounter=63, freezed=false, freezeReason=null, client=[addr=redis://127.0.0.1:6379], nodeType=MASTER, firstFail=0]]] using node 127.0.0.1/127.0.0.1:6379... RedisConnection@1063763790 [redisClient=[addr=redis://127.0.0.1:6379], channel=[id: 0x8c7642c9, L:/127.0.0.1:57770 - R:127.0.0.1/127.0.0.1:6379]]
22:09:27.627 [redisson-netty-1-8] DEBUG org.redisson.command.CommandAsyncService - connection released for command (EVAL) and params [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, keyLock, 30000, b4af98de-c972-4bba-ae9b-73428bc0d0fa:22] from slot NodeSource [slot=null, addr=null, redisClient=null, redirect=null, entry=MasterSlaveEntry [masterEntry=[freeSubscribeConnectionsAmount=0, freeSubscribeConnectionsCounter=49, freeConnectionsAmount=32, freeConnectionsCounter=64, freezed=false, freezeReason=null, client=[addr=redis://127.0.0.1:6379], nodeType=MASTER, firstFail=0]]] using connection RedisConnection@1063763790 [redisClient=[addr=redis://127.0.0.1:6379], channel=[id: 0x8c7642c9, L:/127.0.0.1:57770 - R:127.0.0.1/127.0.0.1:6379]]
窗口1正在出售第1张票
22:09:27.727 [窗口1] DEBUG org.redisson.command.CommandAsyncService - acquired connection for command (EVAL) and params [if (redis.call('exists', KEYS[1]) == 0) then redis.call('publish', KEYS[2], ARGV[1]); return 1; end;if (redis.call('hexists', KEYS[1], ARGV[3]) == 0) then return nil;end; local counter = redis.call('hincrby', KEYS[1], ARGV[3], -1); if (counter > 0) then redis.call('pexpire', KEYS[1], ARGV[2]); return 0; else redis.call('del', KEYS[1]); redis.call('publish', KEYS[2], ARGV[1]); return 1; end; return nil;, 2, keyLock, redisson_lock__channel:{keyLock}, 0, 30000, b4af98de-c972-4bba-ae9b-73428bc0d0fa:21] from slot NodeSource [slot=null, addr=null, redisClient=null, redirect=null, entry=MasterSlaveEntry [masterEntry=[freeSubscribeConnectionsAmount=0, freeSubscribeConnectionsCounter=49, freeConnectionsAmount=31, freeConnectionsCounter=63, freezed=false, freezeReason=null, client=[addr=redis://127.0.0.1:6379], nodeType=MASTER, firstFail=0]]] using node 127.0.0.1/127.0.0.1:6379... RedisConnection@386270367 [redisClient=[addr=redis://127.0.0.1:6379], channel=[id: 0xa7d442f5, L:/127.0.0.1:57746 - R:127.0.0.1/127.0.0.1:6379]]
22:09:27.727 [redisson-netty-1-1] DEBUG org.redisson.command.CommandAsyncService - connection released for command (EVAL) and params [if (redis.call('exists', KEYS[1]) == 0) then redis.call('publish', KEYS[2], ARGV[1]); return 1; end;if (redis.call('hexists', KEYS[1], ARGV[3]) == 0) then return nil;end; local counter = redis.call('hincrby', KEYS[1], ARGV[3], -1); if (counter > 0) then redis.call('pexpire', KEYS[1], ARGV[2]); return 0; else redis.call('del', KEYS[1]); redis.call('publish', KEYS[2], ARGV[1]); return 1; end; return nil;, 2, keyLock, redisson_lock__channel:{keyLock}, 0, 30000, b4af98de-c972-4bba-ae9b-73428bc0d0fa:21] from slot NodeSource [slot=null, addr=null, redisClient=null, redirect=null, entry=MasterSlaveEntry [masterEntry=[freeSubscribeConnectionsAmount=0, freeSubscribeConnectionsCounter=49, freeConnectionsAmount=32, freeConnectionsCounter=64, freezed=false, freezeReason=null, client=[addr=redis://127.0.0.1:6379], nodeType=MASTER, firstFail=0]]] using connection RedisConnection@386270367 [redisClient=[addr=redis://127.0.0.1:6379], channel=[id: 0xa7d442f5, L:/127.0.0.1:57746 - R:127.0.0.1/127.0.0.1:6379]]
22:09:27.728 [窗口3] DEBUG org.redisson.command.CommandAsyncService - acquired connection for command (EVAL) and params [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, keyLock, 30000, b4af98de-c972-4bba-ae9b-73428bc0d0fa:23] from slot NodeSource [slot=null, addr=null, redisClient=null, redirect=null, entry=MasterSlaveEntry [masterEntry=[freeSubscribeConnectionsAmount=0, freeSubscribeConnectionsCounter=49, freeConnectionsAmount=31, freeConnectionsCounter=63, freezed=false, freezeReason=null, client=[addr=redis://127.0.0.1:6379], nodeType=MASTER, firstFail=0]]] using node 127.0.0.1/127.0.0.1:6379... RedisConnection@663006544 [redisClient=[addr=redis://127.0.0.1:6379], channel=[id: 0x61910396, L:/127.0.0.1:57757 - R:127.0.0.1/127.0.0.1:6379]]
22:09:27.729 [redisson-netty-1-7] DEBUG org.redisson.command.CommandAsyncService - connection released for command (EVAL) and params [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, keyLock, 30000, b4af98de-c972-4bba-ae9b-73428bc0d0fa:23] from slot NodeSource [slot=null, addr=null, redisClient=null, redirect=null, entry=MasterSlaveEntry [masterEntry=[freeSubscribeConnectionsAmount=0, freeSubscribeConnectionsCounter=49, freeConnectionsAmount=32, freeConnectionsCounter=64, freezed=false, freezeReason=null, client=[addr=redis://127.0.0.1:6379], nodeType=MASTER, firstFail=0]]] using connection RedisConnection@663006544 [redisClient=[addr=redis://127.0.0.1:6379], channel=[id: 0x61910396, L:/127.0.0.1:57757 - R:127.0.0.1/127.0.0.1:6379]]
22:09:27.729 [窗口3] DEBUG org.redisson.command.CommandAsyncService - acquired connection for command (EVAL) and params [if (redis.call('exists', KEYS[1]) == 0) then redis.call('publish', KEYS[2], ARGV[1]); return 1; end;if (redis.call('hexists', KEYS[1], ARGV[3]) == 0) then return nil;end; local counter = redis.call('hincrby', KEYS[1], ARGV[3], -1); if (counter > 0) then redis.call('pexpire', KEYS[1], ARGV[2]); return 0; else redis.call('del', KEYS[1]); redis.call('publish', KEYS[2], ARGV[1]); return 1; end; return nil;, 2, keyLock, redisson_lock__channel:{keyLock}, 0, 30000, b4af98de-c972-4bba-ae9b-73428bc0d0fa:23] from slot NodeSource [slot=null, addr=null, redisClient=null, redirect=null, entry=MasterSlaveEntry [masterEntry=[freeSubscribeConnectionsAmount=0, freeSubscribeConnectionsCounter=49, freeConnectionsAmount=31, freeConnectionsCounter=63, freezed=false, freezeReason=null, client=[addr=redis://127.0.0.1:6379], nodeType=MASTER, firstFail=0]]] using node 127.0.0.1/127.0.0.1:6379... RedisConnection@1739852710 [redisClient=[addr=redis://127.0.0.1:6379], channel=[id: 0x94ca81c4, L:/127.0.0.1:57750 - R:127.0.0.1/127.0.0.1:6379]]
22:09:27.729 [redisson-netty-1-7] DEBUG org.redisson.command.CommandAsyncService - connection released for command (EVAL) and params [if (redis.call('exists', KEYS[1]) == 0) then redis.call('publish', KEYS[2], ARGV[1]); return 1; end;if (redis.call('hexists', KEYS[1], ARGV[3]) == 0) then return nil;end; local counter = redis.call('hincrby', KEYS[1], ARGV[3], -1); if (counter > 0) then redis.call('pexpire', KEYS[1], ARGV[2]); return 0; else redis.call('del', KEYS[1]); redis.call('publish', KEYS[2], ARGV[1]); return 1; end; return nil;, 2, keyLock, redisson_lock__channel:{keyLock}, 0, 30000, b4af98de-c972-4bba-ae9b-73428bc0d0fa:23] from slot NodeSource [slot=null, addr=null, redisClient=null, redirect=null, entry=MasterSlaveEntry [masterEntry=[freeSubscribeConnectionsAmount=0, freeSubscribeConnectionsCounter=49, freeConnectionsAmount=32, freeConnectionsCounter=64, freezed=false, freezeReason=null, client=[addr=redis://127.0.0.1:6379], nodeType=MASTER, firstFail=0]]] using connection RedisConnection@1739852710 [redisClient=[addr=redis://127.0.0.1:6379], channel=[id: 0x94ca81c4, L:/127.0.0.1:57750 - R:127.0.0.1/127.0.0.1:6379]]
22:09:27.730 [窗口2] DEBUG org.redisson.command.CommandAsyncService - acquired connection for command (EVAL) and params [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, keyLock, 30000, b4af98de-c972-4bba-ae9b-73428bc0d0fa:22] from slot NodeSource [slot=null, addr=null, redisClient=null, redirect=null, entry=MasterSlaveEntry [masterEntry=[freeSubscribeConnectionsAmount=0, freeSubscribeConnectionsCounter=49, freeConnectionsAmount=31, freeConnectionsCounter=63, freezed=false, freezeReason=null, client=[addr=redis://127.0.0.1:6379], nodeType=MASTER, firstFail=0]]] using node 127.0.0.1/127.0.0.1:6379... RedisConnection@1820718714 [redisClient=[addr=redis://127.0.0.1:6379], channel=[id: 0x6d3c89be, L:/127.0.0.1:57762 - R:127.0.0.1/127.0.0.1:6379]]
22:09:27.731 [redisson-netty-1-7] DEBUG org.redisson.command.CommandAsyncService - connection released for command (EVAL) and params [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, keyLock, 30000, b4af98de-c972-4bba-ae9b-73428bc0d0fa:22] from slot NodeSource [slot=null, addr=null, redisClient=null, redirect=null, entry=MasterSlaveEntry [masterEntry=[freeSubscribeConnectionsAmount=0, freeSubscribeConnectionsCounter=49, freeConnectionsAmount=32, freeConnectionsCounter=64, freezed=false, freezeReason=null, client=[addr=redis://127.0.0.1:6379], nodeType=MASTER, firstFail=0]]] using connection RedisConnection@1820718714 [redisClient=[addr=redis://127.0.0.1:6379], channel=[id: 0x6d3c89be, L:/127.0.0.1:57762 - R:127.0.0.1/127.0.0.1:6379]]
22:09:27.732 [窗口2] DEBUG org.redisson.command.CommandAsyncService - acquired connection for command (EVAL) and params [if (redis.call('exists', KEYS[1]) == 0) then redis.call('publish', KEYS[2], ARGV[1]); return 1; end;if (redis.call('hexists', KEYS[1], ARGV[3]) == 0) then return nil;end; local counter = redis.call('hincrby', KEYS[1], ARGV[3], -1); if (counter > 0) then redis.call('pexpire', KEYS[1], ARGV[2]); return 0; else redis.call('del', KEYS[1]); redis.call('publish', KEYS[2], ARGV[1]); return 1; end; return nil;, 2, keyLock, redisson_lock__channel:{keyLock}, 0, 30000, b4af98de-c972-4bba-ae9b-73428bc0d0fa:22] from slot NodeSource [slot=null, addr=null, redisClient=null, redirect=null, entry=MasterSlaveEntry [masterEntry=[freeSubscribeConnectionsAmount=0, freeSubscribeConnectionsCounter=49, freeConnectionsAmount=31, freeConnectionsCounter=63, freezed=false, freezeReason=null, client=[addr=redis://127.0.0.1:6379], nodeType=MASTER, firstFail=0]]] using node 127.0.0.1/127.0.0.1:6379... RedisConnection@562654563 [redisClient=[addr=redis://127.0.0.1:6379], channel=[id: 0x71b3a473, L:/127.0.0.1:57756 - R:127.0.0.1/127.0.0.1:6379]]
22:09:27.733 [redisson-netty-1-1] DEBUG org.redisson.command.CommandAsyncService - connection released for command (EVAL) and params [if (redis.call('exists', KEYS[1]) == 0) then redis.call('publish', KEYS[2], ARGV[1]); return 1; end;if (redis.call('hexists', KEYS[1], ARGV[3]) == 0) then return nil;end; local counter = redis.call('hincrby', KEYS[1], ARGV[3], -1); if (counter > 0) then redis.call('pexpire', KEYS[1], ARGV[2]); return 0; else redis.call('del', KEYS[1]); redis.call('publish', KEYS[2], ARGV[1]); return 1; end; return nil;, 2, keyLock, redisson_lock__channel:{keyLock}, 0, 30000, b4af98de-c972-4bba-ae9b-73428bc0d0fa:22] from slot NodeSource [slot=null, addr=null, redisClient=null, redirect=null, entry=MasterSlaveEntry [masterEntry=[freeSubscribeConnectionsAmount=0, freeSubscribeConnectionsCounter=49, freeConnectionsAmount=32, freeConnectionsCounter=64, freezed=false, freezeReason=null, client=[addr=redis://127.0.0.1:6379], nodeType=MASTER, firstFail=0]]] using connection RedisConnection@562654563 [redisClient=[addr=redis://127.0.0.1:6379], channel=[id: 0x71b3a473, L:/127.0.0.1:57756 - R:127.0.0.1/127.0.0.1:6379]]
也就是源码的这部分
并且redisson还有watch dog机制,也就是开启守护线程,当业务代码在超时时间内还没执行完的时候帮自动续时功能