Java 8
Spring Boot 2.5.3
org.redisson:redisson:3.16.4
Redis 單機版,4.0.9 (on Ubuntu)
---
Redisson 可以用來做 分佈式鎖。
這是孤使用前的認知,本文也是記錄其分佈式鎖的簡單使用。
看過 阿里雲的文檔 才知,哦,Redisson原來號稱【經過近4年日日夜夜的努力,Redisson終於在2019年1月16日成爲GitHub裏星星最多的Redis Java客戶端】。
原來,不僅僅是做 分佈式鎖啊。
https://github.com/redisson/redisson
https://developer.aliyun.com/profile/7cqhdxtuiehao
https://mvnrepository.com/artifact/org.redisson/redisson
本文根據其 GitHub的quick-start 進行試驗。
添加依賴包:最新版本
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.16.4</version>
</dependency>
添加配置:
新建一個 RedissonClient Bean
package com.example.webbasic.config;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Redisson配置
* @author ben
* @date 2021-11-29 20:56:01 CST
*/
@Configuration
public class RedissonConfig {
@Bean
public RedissonClient redissonClient() {
Config cf = new Config();
// Redis服務器是單機的,配置爲 集羣模式,發生異常,啓動失敗
// cf.useClusterServers()
// .addNodeAddress("redis://192.168.0.111:6379");
// 單機配置,成功
cf.useSingleServer().setAddress("redis://mylinux:6379");
RedissonClient rc = Redisson.create(cf);
return rc;
}
}
注,上面的配置支持 單機Redis,除了單機模式,還可以支持 主從、集羣 等模式(useXXX方法)。
使用上一步的 RedissonClient Bean 實現分佈式鎖:
package com.example.webbasic.runner;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
/**
* 基於Redisson的分佈式鎖測試
* @author ben
* @date 2021-11-29 21:05:19 CST
*/
@Component
public class RedissonDistLock implements ApplicationRunner {
@Autowired
private RedissonClient rc;
@Value("${server.port}")
private String port;
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println("start: port=" + port);
String mykey = "web-basic-key";
RLock rl = rc.getLock(mykey);
IntStream.range(0, 10).forEach(i->{
rl.lock();
System.out.println("port=" + port + ", i=" + i + ", 1, now=" + new Date());
try {
TimeUnit.SECONDS.sleep(20);
System.out.println("port=" + port + ", i=" + i + ", 2");
} catch (InterruptedException e) {
System.out.println("port=" + port + ", i=" + i + ", 3 異常, e=" + e.getClass());
// e.printStackTrace();
} finally {
rl.unlock();
System.out.println("port=" + port + ", i=" + i + ", 4, now=" + new Date());
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}
rc.getLock(mykey) 生成了鎖 RLock對象,執行此對象的 lock()、unlock() 實現分佈式鎖。
Redis中鍵的變化:
啓動項目:分別在端口 5555、9999 運行
注意,在測試程序的 rl.unlock() 後添加了 休眠,如果不添加的話,最先運行的進程會一直鎖住執行——速度太快,而後運行的一直得不到鎖。
解決這個問題,除了 加休眠(不合理)外,還可以調用 rc.getFairLock(mykey) 來處理:公平鎖——這纔是 正確的用法。
使用 公平鎖時,Redis中數據的變化:多了兩個,類型也不同了
127.0.0.1:6379> keys *
3) "redisson_lock_timeout:{web-basic-key}"
4) "redisson_lock_queue:{web-basic-key}"
6) "web-basic-key"
127.0.0.1:6379>
127.0.0.1:6379> type redisson_lock_timeout:{web-basic-key}
zset
127.0.0.1:6379>
127.0.0.1:6379> type redisson_lock_queue:{web-basic-key}
list
127.0.0.1:6379>
127.0.0.1:6379> type web-basic-key
hash
127.0.0.1:6379>
》》》全文完《《《
Redisson 還有更多功能待探索。
疑問:
使用Redisson的時候,怎麼沒有添加 Redis驅動呢?
聽說Redisson做分佈式鎖的時候有缺點,是什麼呢?還需探索。