SpringBoot Redisson 集成的實現(xiàn)示例
一、引入依賴
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>3.23.5</version>
</dependency>redison-spring-boot-starter依賴于與最新版本的spring-boot兼容的redison-spring數(shù)據(jù)模塊。降級redison彈簧數(shù)據(jù)模塊(如有必要),以支持以前的spring Boot版本:
| redisson-spring-data module name | Spring Boot version |
|---|---|
| redisson-spring-data-16 | 1.3.y |
| redisson-spring-data-17 | 1.4.y |
| redisson-spring-data-18 | 1.5.y |
| redisson-spring-data-2x | 2.x.y |
| redisson-spring-data-3x | 3.x.y |
二、添加配置文件
使用 common Spring Boot 3.x+ settings:
spring:
data:
redis:
database:
host:
port:
password:
ssl:
timeout:
connectTimeout:
clientName:
cluster:
nodes:
sentinel:
master:
nodes:使用common Spring Boot up to 2.7.x settings:
spring:
redis:
database:
host:
port:
password:
ssl:
timeout:
connectTimeout:
clientName:
cluster:
nodes:
sentinel:
master:
nodes:配置redision屬性(application.yaml):
spring:
redis:
redisson:
config: |
clusterServersConfig:
idleConnectionTimeout: 10000
connectTimeout: 10000
timeout: 3000
retryAttempts: 3
retryInterval: 1500
failedSlaveReconnectionInterval: 3000
failedSlaveCheckInterval: 60000
password: null
subscriptionsPerConnection: 5
clientName: null
loadBalancer: !<org.redisson.connection.balancer.RoundRobinLoadBalancer> {}
subscriptionConnectionMinimumIdleSize: 1
subscriptionConnectionPoolSize: 50
slaveConnectionMinimumIdleSize: 24
slaveConnectionPoolSize: 64
masterConnectionMinimumIdleSize: 24
masterConnectionPoolSize: 64
readMode: "SLAVE"
subscriptionMode: "SLAVE"
nodeAddresses:
- "redis://127.0.0.1:7004"
- "redis://127.0.0.1:7001"
- "redis://127.0.0.1:7000"
scanInterval: 1000
pingConnectionInterval: 0
keepAlive: false
tcpNoDelay: false
threads: 16
nettyThreads: 32
codec: !<org.redisson.codec.Kryo5Codec> {}
transportMode: "NIO"
三、使用 RedissonClient
除了常用的 StringRedisTemplate 外,我們還可以注入如下由 Redisson 提供的 Bean:
RedissonClientRedissonRxClient(響應(yīng)式)RedissonReactiveClient(響應(yīng)式)RedisTemplateReactiveRedisTemplate(響應(yīng)式)
四、接下來,我們使用 RedissonClient 來實現(xiàn)一個分布式鎖,以進行測試:
import org.junit.jupiter.api.Test;
import org.redisson.api.RedissonClient;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.Lock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class Application {
static final Logger logger = LoggerFactory.getLogger(DemoApplicationTests.class);
// 注入 RedissonClient
@Autowired
RedissonClient redissonClient;
// 計數(shù)器
private int count;
@Test
public void LockOp throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(1000);
for (int i = 0; i < 1000; i++) {
new Thread(() -> {
// 每個線程都創(chuàng)建自己的鎖對象
// 這是基于 Redis 實現(xiàn)的分布式鎖
Lock lock = this.redissonClient.getLock("counterLock");
try {
// 上鎖
lock.lock();
// 計數(shù)器自增 1
this.count = this.count + 1;
} finally {
// 釋放鎖
lock.unlock();
}
countDownLatch.countDown();
}).start();
}
countDownLatch.await();
logger.info("count = {}", this.count);
}如上。我們在測試類中注入了 RedissonClient Bean,并且定義了一個 count 屬性。在測試方法中,啟動 1000 個線程對 count 屬性進行 +1 操作。其中,每個線程都通過 RedissonClient 獲取分布式鎖來控制對變量的并發(fā)修改。
運行測試,輸出的日志如下:
INFO 4840 --- [ main] c.s.demo.test.DemoApplicationTests : count = 1000
最后的結(jié)果是 1000,分布式鎖生效。
五、 復(fù)雜多維對象結(jié)構(gòu)和對象引用的支持
Redisson突破了Redis數(shù)據(jù)結(jié)構(gòu)維度的限制,通過一個特殊引用對象的幫助,Redisson允許以任意的組合方式構(gòu)建多維度的復(fù)雜對象結(jié)構(gòu),實現(xiàn)了對象之間的類似傳統(tǒng)數(shù)據(jù)庫里的關(guān)聯(lián)關(guān)系。使用范例如下:
RMap<RSet<RList>, RList<RMap>> map = redisson.getMap("myMap");
RSet<RList> set = redisson.getSet("mySet");
RList<RMap> list = redisson.getList("myList");
map.put(set, list);
// 在特殊引用對象的幫助下,我們甚至可以構(gòu)建一個循環(huán)引用,這是通過普通序列化方式實現(xiàn)不了的。
set.add(list);
list.add(map);可能您已經(jīng)注意到了,在map包含的元素發(fā)生改變以后,我們無需再次“保存/持久”這些對象。因為map對象所記錄的并不是序列化以后的值,而是元素對象的引用。這讓Redisson提供的對象在使用方法上,與普通Java對象的使用方法一致。從而讓Redis成為內(nèi)存的一部分,而不僅僅是一個儲存空間。
以上范例中,一共創(chuàng)建了三個Redis數(shù)據(jù)結(jié)構(gòu):一個Redis HASH,一個Redis SET和一個Redis LIST。
六、 命令的批量執(zhí)行
多個連續(xù)命令可以通過RBatch對象在一次網(wǎng)絡(luò)會話請求里合并發(fā)送,這樣省去了產(chǎn)生多個請求消耗的時間和資源。這在Redis中叫做管道。
用戶可以通過以下方式調(diào)整通過管道方式發(fā)送命令的方式:
BatchOptions options = BatchOptions.defaults() // 指定執(zhí)行模式 // // ExecutionMode.REDIS_READ_ATOMIC - 所有命令緩存在Redis節(jié)點中,以原子性事務(wù)的方式執(zhí)行。 // // ExecutionMode.REDIS_WRITE_ATOMIC - 所有命令緩存在Redis節(jié)點中,以原子性事務(wù)的方式執(zhí)行。 // // ExecutionMode.IN_MEMORY - 所有命令緩存在Redisson本機內(nèi)存中統(tǒng)一發(fā)送,但逐一執(zhí)行(非事務(wù))。默認模式。 // // ExecutionMode.IN_MEMORY_ATOMIC - 所有命令緩存在Redisson本機內(nèi)存中統(tǒng)一發(fā)送,并以原子性事務(wù)的方式執(zhí)行。 // .executionMode(ExecutionMode.IN_MEMORY) // 告知Redis不用返回結(jié)果(可以減少網(wǎng)絡(luò)用量) .skipResult() // 將寫入操作同步到從節(jié)點 // 同步到2個從節(jié)點,等待時間為1秒鐘 .syncSlaves(2, 1, TimeUnit.SECONDS) // 處理結(jié)果超時為2秒鐘 .responseTimeout(2, TimeUnit.SECONDS) // 命令重試等待間隔時間為2秒鐘 .retryInterval(2, TimeUnit.SECONDS); // 命令重試次數(shù)。僅適用于未發(fā)送成功的命令 .retryAttempts(4);
使用方式如下:
RBatch batch = redisson.createBatch();
batch.getMap("test").fastPutAsync("1", "2");
batch.getMap("test").fastPutAsync("2", "3");
batch.getMap("test").putAsync("2", "5");
batch.getAtomicLongAsync("counter").incrementAndGetAsync();
batch.getAtomicLongAsync("counter").incrementAndGetAsync();
BatchResult res = batch.execute();
// 或者
Future<BatchResult> asyncRes = batch.executeAsync();
List<?> response = res.getResponses();
res.getSyncedSlaves();
在集群模式下,所有的命令會按各個槽所在的節(jié)點,篩選分配到各個節(jié)點并同時發(fā)送。每個節(jié)點返回的結(jié)果將會匯總到最終的結(jié)果列表里。
七、Redisson事務(wù)
Redisson為RMap、RMapCache、RLocalCachedMap、RSet、RSetCache和RBucket這樣的對象提供了具有ACID屬性的事務(wù)功能。Redisson事務(wù)通過分布式鎖保證了連續(xù)寫入的原子性,同時在內(nèi)部通過操作指令隊列實現(xiàn)了Redis原本沒有的提交與滾回功能。當(dāng)提交與滾回遇到問題的時候,將通過org.redisson.transaction.TransactionException告知用戶。
目前支持的環(huán)境如下: SINGLE, MASTER/SLAVE, SENTINEL, ELASTICACHE REPLICATED, AZURE CACHE, RLEC。
Redisson事務(wù)支持的事務(wù)隔離等級為: READ_COMMITTED,即僅讀取提交后的結(jié)果。
另見 Spring事務(wù)管理器 和本章 XA事務(wù)(XA Transactions)。
以下選項可以用來配置事務(wù)屬性:
TransactionOptions options = TransactionOptions.defaults() // 設(shè)置參與本次事務(wù)的主節(jié)點與其從節(jié)點同步的超時時間。 // 默認值是5秒。 .syncSlavesTimeout(5, TimeUnit.SECONDS) // 處理結(jié)果超時。 // 默認值是3秒。 .responseTimeout(3, TimeUnit.SECONDS) // 命令重試等待間隔時間。僅適用于未發(fā)送成功的命令。 // 默認值是1.5秒。 .retryInterval(2, TimeUnit.SECONDS) // 命令重試次數(shù)。僅適用于未發(fā)送成功的命令。 // 默認值是3次。 .retryAttempts(3) // 事務(wù)超時時間。如果規(guī)定時間內(nèi)沒有提交該事務(wù)則自動滾回。 // 默認值是5秒。 .timeout(5, TimeUnit.SECONDS);
代碼范例:
RTransaction transaction = redisson.createTransaction(TransactionOptions.defaults());
RMap<String, String> map = transaction.getMap("myMap");
map.put("1", "2");
String value = map.get("3");
RSet<String> set = transaction.getSet("mySet")
set.add(value);
try {
transaction.commit();
} catch(TransactionException e) {
transaction.rollback();
}八、XA事務(wù)(XA Transactions)
Redisson提供了XAResource標(biāo)準的實現(xiàn)。該實現(xiàn)可用于JTA事務(wù)中。
另見本章Redisson事務(wù)和Spring事務(wù)管理器。
該功能僅適用于Redisson PRO版本
代碼范例:
// Transaction對象可以從所有兼容JTA接口的事務(wù)管理器中獲取。
Transaction globalTransaction = transactionManager.getTransaction();
RXAResource xaResource = redisson.getXAResource();
globalTransaction.enlistResource(xaResource);
RTransaction transaction = xaResource.getTransaction();
RBucket<String> bucket = transaction.getBucket("myBucket");
bucket.set("simple");
RMap<String, String> map = transaction.getMap("myMap");
map.put("myKey", "myValue");
transactionManager.commit();到此這篇關(guān)于SpringBoot Redisson 集成的實現(xiàn)示例的文章就介紹到這了,更多相關(guān)SpringBoot Redisson 集成內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Springboot整合SpringSecurity的完整案例詳解
Spring Security是基于Spring生態(tài)圈的,用于提供安全訪問控制解決方案的框架,Spring Security登錄認證主要涉及兩個重要的接口 UserDetailService和UserDetails接口,本文對Springboot整合SpringSecurity過程給大家介紹的非常詳細,需要的朋友參考下吧2024-01-01
java實現(xiàn)后臺數(shù)據(jù)顯示在前端
這篇文章主要為大家詳細介紹了java實現(xiàn)后臺數(shù)據(jù)顯示在前端,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-02-02
Win10系統(tǒng)下配置java環(huán)境變量的全過程
這篇文章主要給大家介紹了關(guān)于Win10系統(tǒng)下配置java環(huán)境變量的相關(guān)資料,文中通過圖文介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11
jetbrain?fleet對標(biāo)vscode實際操作
Gradle是一個基于Apache Ant和Apache Maven概念項目自動化構(gòu)建開源工具,jetbrain家的fleet(已獲得預(yù)覽權(quán)限)直接對標(biāo)vscode?,?fleet有望超過vscode嗎?今天我們實際操作下2021-12-12
Spring使用@Filter注解創(chuàng)建自定義過濾器
Spring 中鮮為人知但非常有用的注解之一是 @Filter,它支持自定義過濾器,下面我們就來深入研究一下如何使用 Spring 的 @Filter 注解來創(chuàng)建自定義過濾器吧2023-11-11
Java Iterator迭代器與foreach循環(huán)代碼解析
這篇文章主要介紹了Java-Iterator迭代器與foreach循環(huán),主要包括Iterator迭代器接口的操作方法和foreach 循環(huán)語法解析,需要的朋友可以參考下2022-04-04

