springboot集成redisson的三種方式
前言
本文主要描述springboot繼承redisson的幾種方式以及redisson分布式鎖的使用;
一、redisson簡(jiǎn)介?
Redisson是架設(shè)在Redis基礎(chǔ)上的一個(gè)Java駐內(nèi)存數(shù)據(jù)網(wǎng)格(In-Memory Data Grid)。
Redisson在基于NIO的Netty框架上,充分的利用了Redis鍵值數(shù)據(jù)庫(kù)提供的一系列優(yōu)勢(shì),在Java實(shí)用工具包中常用接口的基礎(chǔ)上,為使用者提供了一系列具有分布式特性的常用工具類(lèi)。使得原本作為協(xié)調(diào)單機(jī)多線程并發(fā)程序的工具包獲得了協(xié)調(diào)分布式多機(jī)多線程并發(fā)系統(tǒng)的能力,大大降低了設(shè)計(jì)和研發(fā)大規(guī)模分布式系統(tǒng)的難度。同時(shí)結(jié)合各富特色的分布式服務(wù),更進(jìn)一步簡(jiǎn)化了分布式環(huán)境中程序相互之間的協(xié)作。
最熟為人知的是它的分布式鎖機(jī)制,它有比redis本身更多更強(qiáng)勁的功能
分布式鎖原理 : 發(fā)送一段lua腳本(保證原子性)用以加鎖,其本質(zhì)是搶占key,誰(shuí)先生成key誰(shuí)就有鎖
以后再補(bǔ)一篇原理
二、集成方式
redisson 集成springBoot并不是特別友好,因?yàn)樗鼪](méi)有像redis這樣寫(xiě)自動(dòng)配置類(lèi),故不能僅寫(xiě)配置就能用
引入pom坐標(biāo):
<!--分布式鎖--> <dependency> <groupId>org.redisson</groupId> <artifactId>redisson</artifactId> <version>3.13.6</version> </dependency>
2.1自定義配置+手動(dòng)注入
要點(diǎn):
1.自己寫(xiě)配置屬性
2.自己寫(xiě)@Bean注入redisson
配置類(lèi)
import com.xkj.ecommerce.utils.RedissonLockUtil; import lombok.Data; import org.redisson.Redisson; import org.redisson.api.RedissonClient; import org.redisson.config.Config; import org.redisson.config.SentinelServersConfig; import org.redisson.config.SingleServerConfig; import org.springframework.boot.autoconfigure.AutoConfigureOrder; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.Arrays; /** * @createDate 2021/1/18 */ @Configuration @ConfigurationProperties(prefix = "redisson") @Data @AutoConfigureOrder public class RedissonConfig { private int timeout = 3000; private String address; private String password; private int database = 0; private int connectionPoolSize = 64; private int connectionMinimumIdleSize = 10; private int slaveConnectionPoolSize = 250; private int masterConnectionPoolSize = 250; private String[] sentinelAddresses; private String masterName; public void setSentinelAddresses(String sentinelAddresses) { this.sentinelAddresses = Arrays.stream(sentinelAddresses.split(",")).map(s -> "redis://" + s).toArray(String[]::new); } public void setAddress(String address) { this.address = "redis://" + address; } /** * 哨兵模式自動(dòng)裝配 */ @Bean @ConditionalOnMissingBean(RedissonClient.class) @ConditionalOnProperty(name = "redisson.masterName") public RedissonLockUtil redissonSentinel() { Config config = new Config(); SentinelServersConfig serverConfig = config.useSentinelServers().addSentinelAddress(this.getSentinelAddresses()) .setMasterName(this.getMasterName()) .setTimeout(this.getTimeout()) .setMasterConnectionPoolSize(this.getMasterConnectionPoolSize()) .setSlaveConnectionPoolSize(this.getSlaveConnectionPoolSize()); if (StringUtils.isNotBlank(this.getPassword())) { serverConfig.setPassword(this.getPassword()); } RedissonClient redissonClient = Redisson.create(config); RedissonLockUtil locker = new RedissonLockUtil(); locker.setRedissonClient(redissonClient); return locker; } /** * 單機(jī)模式自動(dòng)裝配 */ @Bean @ConditionalOnProperty(name = "redisson.address") public RedissonLockUtil redissonSingle() { Config config = new Config(); SingleServerConfig serverConfig = config.useSingleServer() .setAddress(this.getAddress()) .setTimeout(this.getTimeout()) .setConnectionPoolSize(this.getConnectionPoolSize()) .setConnectionMinimumIdleSize(this.getConnectionMinimumIdleSize()); if (StringUtils.isNotBlank(this.getPassword())) { serverConfig.setPassword(this.getPassword()); } RedissonClient redissonClient = Redisson.create(config); RedissonLockUtil locker = new RedissonLockUtil(); locker.setRedissonClient(redissonClient); return locker; } }
application.properties
redisson.timeout=3000 .... # 哨兵配置(用英文逗號(hào)隔開(kāi)) # redisson.sentinelAddresses=192.168.2.100:3408,192.168.2.101:3408 # 單機(jī)配置 redisson.address=192.168.2.100:3408
2.2使用Yaml方式批量讀取配置
要點(diǎn):
1.使用redisson官方提供的工具類(lèi),讀取指定配置項(xiàng)
配置類(lèi)
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; import java.io.IOException; @Configuration public class RedissonConfig { @Bean public RedissonClient redisson() throws IOException { // 本例子使用的是yaml格式的配置文件,讀取使用Config.fromYAML,如果是Json文件,則使用Config.fromJSON Config config = Config.fromYAML(RedissonConfig.class.getClassLoader().getResource("redisson-config.yml")); return Redisson.create(config); } }
自行注入到工具類(lèi)中,參考
RedissonClient redissonClient = Redisson.create(config);
RedissonLockUtil locker = new RedissonLockUtil();
locker.setRedissonClient(redissonClient);
redisson-config.yml
2.3使用spring boot自動(dòng)配置類(lèi)
引入springboot-redisson坐標(biāo)
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/org.redisson/redisson-spring-boot-starter --> <dependency> <groupId>org.redisson</groupId> <artifactId>redisson-spring-boot-starter</artifactId> <version>3.12.0</version> </dependency>
與yaml方式類(lèi)似,應(yīng)該屬于進(jìn)階版
application.yml
# 公共的spring配置 spring.redis.database= spring.redis.host= spring.redis.port= spring.redis.password= spring.redis.ssl= spring.redis.timeout= spring.redis.cluster.nodes= spring.redis.sentinel.master= spring.redis.sentinel.nodes= # Redisson 的特殊配置 # 可以從本地的類(lèi)路徑下讀取配置文件 spring.redis.redisson.config=classpath:redisson-config.yml
然后可以直接使用
@Autowired RedissonClient redissonClient;
三、工具類(lèi)
import org.redisson.api.RLock; import org.redisson.api.RedissonClient; import java.util.concurrent.TimeUnit; public class RedissonLockUtil { private static RedissonClient redissonClient; public void setRedissonClient(RedissonClient redissonCli) { redissonClient = redissonCli; } public static RLock lock(String lockKey) { RLock lock = redissonClient.getLock(lockKey); lock.lock(); return lock; } public static RLock lock(String lockKey, int leaseTime) { RLock lock = redissonClient.getLock(lockKey); lock.lock(leaseTime, TimeUnit.SECONDS); return lock; } public static RLock lock(String lockKey, TimeUnit unit, int timeout) { RLock lock = redissonClient.getLock(lockKey); lock.lock(timeout, unit); return lock; } /** * 嘗試獲得鎖,自定義 時(shí)間單位;等待時(shí)長(zhǎng);加鎖時(shí)長(zhǎng) */ public static boolean tryLock(String lockKey, int waitTime, int leaseTime, TimeUnit unit) { RLock lock = redissonClient.getLock(lockKey); try { return lock.tryLock(waitTime, leaseTime, unit); } catch (InterruptedException e) { return false; } } /** * 嘗試獲得鎖,自定義 等待時(shí)長(zhǎng);加鎖時(shí)長(zhǎng) (默認(rèn)為秒) */ public static boolean tryLock(String lockKey, int waitTime, int leaseTime) { RLock lock = redissonClient.getLock(lockKey); try { return lock.tryLock(waitTime, leaseTime, TimeUnit.SECONDS); } catch (InterruptedException e) { return false; } } /** * 嘗試獲得鎖,自定義 等待時(shí)長(zhǎng) (加鎖時(shí)長(zhǎng)不限制;默認(rèn)為秒) */ public static boolean tryLock(String lockKey, int waitTime) { RLock lock = redissonClient.getLock(lockKey); try { return lock.tryLock(waitTime, TimeUnit.SECONDS); } catch (InterruptedException e) { return false; } } /** * 嘗試獲得鎖,自定義 等待時(shí)長(zhǎng) (加鎖時(shí)長(zhǎng)不限制) */ public static boolean tryLock(String lockKey, int waitTime, TimeUnit unit) { RLock lock = redissonClient.getLock(lockKey); try { return lock.tryLock(waitTime, unit); } catch (InterruptedException e) { return false; } } public static void unlock(String lockKey) { RLock lock = redissonClient.getLock(lockKey); lock.unlock(); } public static void unlock(RLock lock) { lock.unlock(); } }
用的時(shí)候就可以直接 RedissonLockUtil.lock("test")
總結(jié)
(據(jù)說(shuō)redisson和redisson-spring-boot-starter用的不是同一套體系,如果考慮引包的兼容性,建議用第三種方式)
到此這篇關(guān)于springboot集成redisson的三種方式的文章就介紹到這了,更多相關(guān)springboot集成redisson內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
優(yōu)化SpringBoot程序啟動(dòng)速度的實(shí)現(xiàn)
本文主要介紹了優(yōu)化SpringBoot程序啟動(dòng)速度的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-01-01Java 反轉(zhuǎn)帶頭結(jié)點(diǎn)的單鏈表并顯示輸出的實(shí)現(xiàn)過(guò)程
這篇文章主要介紹了Java 反轉(zhuǎn)帶頭結(jié)點(diǎn)的單鏈表并顯示輸出,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-11-11如何通過(guò)一張圖搞懂springBoot自動(dòng)注入原理
這篇文章主要給大家介紹了關(guān)于如何通過(guò)一張圖搞懂springBoot自動(dòng)注入原理的相關(guān)資料,文中通過(guò)圖文以及實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2022-02-02java中sleep方法和wait方法的五個(gè)區(qū)別
這篇文章主要介紹了java中sleep方法和wait方法的五個(gè)區(qū)別,sleep?方法和?wait?方法都是用來(lái)將線程進(jìn)入休眠狀態(tài),但是又有一些區(qū)別,下面我們就一起來(lái)看看吧2022-05-05springboot項(xiàng)目連接不上nacos配置,報(bào)‘url‘異常問(wèn)題
這篇文章主要介紹了springboot項(xiàng)目連接不上nacos配置,報(bào)‘url‘異常問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-06-06一篇文章帶你入門(mén)Java數(shù)據(jù)類(lèi)型
下面小編就為大家?guī)?lái)一篇Java的基本數(shù)據(jù)類(lèi)型)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2021-08-08java實(shí)現(xiàn) 二叉搜索樹(shù)功能
這篇文章主要介紹了java實(shí)現(xiàn) 二叉搜索樹(shù)功能,代碼簡(jiǎn)單易懂,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-07-07