Redissonベースの分散ロック
3980 ワード
以前はビジネスで分散ロックが実現されていましたが、redisのカウンタで実現されていました.その方法では、サービスがダウンした場合、keyはredisに永続的に保存されます.
従って、redissonに切り込むと、redissonはロックを取得する際にデッドロック問題を解決し、下位層はluaスクリプトを呼び出すことによってkeyの書き込みと期限切れの設定の原子性を実現する.
詳細redissonの情報は、公式ドキュメントを参照してください.
https://yq.aliyun.com/articles/554765?spm=a2c4e.11155435.0.0.634056a3ail7EF
使用条件
jdk 1.6+, redis 2.8+
導入pom
redissonクライアントサービスの登録
テストコード
従って、redissonに切り込むと、redissonはロックを取得する際にデッドロック問題を解決し、下位層はluaスクリプトを呼び出すことによってkeyの書き込みと期限切れの設定の原子性を実現する.
詳細redissonの情報は、公式ドキュメントを参照してください.
https://yq.aliyun.com/articles/554765?spm=a2c4e.11155435.0.0.634056a3ail7EF
使用条件
jdk 1.6+, redis 2.8+
導入pom
org.redisson
redisson
3.5.4
redissonクライアントサービスの登録
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.concurrent.TimeUnit;
/**
* redis
*
* @author Demon-HY
* @date 2019-8-19
*/
@Service
public class RedissonClientService {
@Value("${redis.host}")
private String redisHost;
@Value("${redis.port}")
private String redisPort;
@Value("${redis.auth}")
private String redisAuth;
@Value("${redis.timeout}")
private Integer redisTimeout;
private RedissonClient redissonClient;
@PostConstruct
public void afterCreation() {
Config config = new Config();
//
config.useSingleServer()
.setAddress(String.format("redis://%s:%s", redisHost, redisPort))
.setPassword(redisAuth)
// , , :10000
.setConnectTimeout(30000)
// , , , :3000
.setReconnectionTimeout(10000)
// , , :3000
.setTimeout(10000)
// retryAttempts( ) , .
// , timeout( ) , :3
.setRetryAttempts(5)
// , , , :1500
.setRetryInterval(3000);
redissonClient = Redisson.create(config);
}
/**
*
*
* @param lockName
* @return
*/
public RLock getLock(String lockName) {
return redissonClient.getLock(lockName);
}
/**
* name
*
* @param lockName
* @param timeout , , , :
* @return
*/
public void lock(String lockName, long timeout) {
RLock lock = getLock(lockName);
//lock timeout ,timeout ,
lock.lock(timeout, TimeUnit.SECONDS);
}
/**
* name ,redisson tryLock , , boolean。
*
* @param lockName
* @param waitTime , , :
* @param timeout , , :
*/
public boolean tryLock(String lockName, long waitTime, long timeout) throws InterruptedException {
RLock lock = getLock(lockName);
//tryLock, ,5 , 。 60 60
return lock.tryLock(waitTime, timeout, TimeUnit.SECONDS);
}
/**
* name
*
* @param lockName
*/
public void unlock(String lockName) {
RLock lock = getLock(lockName);
lock.unlock();
}
}
テストコード
@Autowired
private RedissonClientService redissonClientService;
public void testLock(String lockName) {
RLock lock = redissonClientService.getLock(lockName);
try {
//tryLock, ,0 , 。 180
if (!lock.tryLock(0L, 180L, TimeUnit.SECONDS)) {// ,
logger.warn(" :{} ", lockName);
return;
}
// ,
// ...
} catch (Exception e) {
logger.error(" ");
} finally {
lock.unlock();
}
}