Biblioteca de clases de herramientas de Redisson
Recomiendo una biblioteca de clases de herramientas basada en el desarrollo de Redis. ¡Esta biblioteca de clases proporciona muchas funciones prácticas, como limitación de corriente, filtro de floración, bloqueo distribuido, etc.!
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.16.8</version>
</dependency>
Hoy solo analizaremos la implementación de bloqueos distribuidos Redisson proporciona muchas formas de bloqueo, como bloqueos sin bloqueo, bloqueos de bloqueo y bloqueos justos.
Además, se proporciona una función de retraso automático. Cuando una tarea no se completa, Redisson continuará extendiendo el período de bloqueo a través de Watch Dog.
Bloqueo de adquisición de bloqueo
// 阻塞式获取锁,并且是重入锁
RLock lock = client.getLock("testLock");
try {
lock.lock();
lock.lock();
// 执行业务逻辑
} finally {
lock.unlock();
lock.unlock();
}
adquisición de bloqueo sin bloqueo
RLock lock = client.getLock("lock");
if (lock.tryLock()) {
System.out.println("获锁成功");
} else {
System.out.println("获锁失败");
}
¿Cómo implementa Redisson un bloqueo de reentrada?
secuencia de comandos de ejecución de bloqueo
entrada de guión
parámetro | sentido |
---|---|
LLAVES[1] | nombre de bloqueo |
ARGV[1] | Tiempo de espera de bloqueo (milisegundos) |
ARGV[2] | ID único del cliente: ID de subproceso |
// 锁不存在
if (redis.call('exists', KEYS[1]) == 0) then
// 新建锁,加锁次数设为1,并设置超时时间
redis.call('hincrby', 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
// 当前线程已经获取到锁了,将加锁次数加1
redis.call('hincrby', KEYS[1], ARGV[2], 1);
redis.call('pexpire', KEYS[1], ARGV[1]);
return nil;
end;
// 加锁失败
return redis.call('pttl', KEYS[1]);
Devuelve cero si el bloqueo es exitoso; de lo contrario, devuelve el tiempo restante del bloqueo.
Desbloquear secuencia de comandos de ejecución
entrada de guión
parámetro | sentido |
---|---|
LLAVES[1] | nombre de bloqueo |
LLAVES[2 | Desbloquee el canal del mensaje, el nombre del canal, redisson_lock__channel:{lock name} |
ARGV[1] | Fijo en 0, Redisson define el mensaje de desbloqueo para que se fije en 0 |
ARGV[2] | tiempo de espera de bloqueo |
ARGV[3] | ID único del cliente: ID de subproceso |
// 为0表示锁不存在
if (redis.call('hexists', KEYS[1], ARGV[3]) == 0) then
return nil;
end;
// 将加锁次数减1
local counter = redis.call('hincrby', KEYS[1], ARGV[3], -1);
if (counter > 0) then
// 当前线程持有锁,设置超时时间
redis.call('pexpire', KEYS[1], ARGV[2]);
return 0;
else
// 加锁次数为0了,直接删除锁,并广播释放锁的消息
redis.call('del', KEYS[1]);
redis.call('publish', KEYS[2], ARGV[1]);
return 1;
end;
return nil;
¿Por qué quieres publicar un mensaje cuando el desbloqueo es exitoso?
Debido a que el subproceso que adquiere el bloqueo mediante el bloqueo no sigue intentando adquirir el bloqueo todo el tiempo, se bloqueará.Cuando reciba el mensaje de desbloqueo, se despertará y comenzará a tomar el bloqueo nuevamente.
¿Cómo implementa Redisson el retraso automático de los bloqueos?
Para evitar que el bloqueo se libere correctamente, generalmente necesitamos establecer un tiempo de espera para el bloqueo, pero esto generará nuevos problemas.
Si el tiempo de espera del bloqueo se establece en 10 s, pero la tarea no se ejecuta dentro de los 10 s, el bloqueo se liberará y otros subprocesos tendrán problemas para adquirir el bloqueo.
Para solucionar este problema, Redisson proporciona un mecanismo de retardo automático del perro guardián, es decir, cuando el bloqueo es exitoso. Abra un subproceso en segundo plano, pase el threadId del bloqueo exitoso y el subproceso en segundo plano verifica cada 10 segundos para ver si el subproceso que actualmente tiene el bloqueo es el threadId. .
Cabe señalar que el tiempo de espera especificado no se puede mostrar al bloquear, de lo contrario, el perro guardián no tendrá efecto.
Cuando el tiempo de espera del bloqueo especificado no se muestra al bloquear, el tiempo de espera del bloqueo es la propiedad lockWatchdogTimeout de la clase Config. El valor predeterminado de esta propiedad es 30 s (configurable) y el tiempo para la verificación automática del mecanismo de vigilancia siempre es igual al tiempo de espera del bloqueo 1/3
Blog de referencia
[1]https://www.cnblogs.com/huangwentian/p/14622441.html?share_token=901429ee-a792-4f2a-87f9-20c47b7cc91c