最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot整合Redisson實踐

 更新時間:2026年03月13日 09:40:04   作者:- Hola -  
Redisson是Redis的Java客戶端,提供了許多分布式服務,如分布式鎖、讀寫鎖、信號量和閉鎖等,簡化了分布式系統(tǒng)的設計和研發(fā)難度

簡介

Redisson 是架設在 Redis 基礎上的一個 Java 駐內(nèi)存數(shù)據(jù)網(wǎng)格(In-Memory Data Grid)。充分 的利用了 Redis 鍵值數(shù)據(jù)庫提供的一系列優(yōu)勢,基于 Java 實用工具包中常用接口,為使用者 提供了一系列具有分布式特性的常用工具類。

使得原本作為協(xié)調(diào)單機多線程并發(fā)程序的工 具包獲得了協(xié)調(diào)分布式多機多線程并發(fā)系統(tǒng)的能力,大大降低了設計和研發(fā)大規(guī)模分布式 系統(tǒng)的難度。同時結(jié)合各富特色的分布式服務,更進一步簡化了分布式環(huán)境中程序相互之間的協(xié)作。 

一.簡單使用

1、導入依賴

        <!--使用redisson作為分布式鎖-->
        <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson</artifactId>
            <version>3.16.8</version>
        </dependency>

2、新建Redisson配置

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;

@Configuration
public class MyRedissonConfig {
    /**
     * 所有對Redisson的使用都是通過RedissonClient對象
     * @return
     */
    @Bean(destroyMethod = "shutdown")
    public RedissonClient redissonClient(){
        // 創(chuàng)建配置 指定redis地址及節(jié)點信息
        Config config = new Config();
        config.useSingleServer().setAddress("XXX.XX.XX.X(redis地址):端口").setPassword("xxxxxxxxx");

        // 根據(jù)config創(chuàng)建出RedissonClient實例
        RedissonClient redissonClient = Redisson.create(config);
        return redissonClient;
    }

}

 3、測試

 @Autowired
    RedissonClient redissonClient;


    @Test
    void redisson(){
        System.out.println(redissonClient);
    }

運行測試代碼發(fā)現(xiàn)控制臺有異常,報錯信息為 :

java.lang.IllegalArgumentException: Redis url should start with redis:// or rediss:// (for SSL connection)

提示我們要在地址前加上redis:// ,SSL連接則需要加上rediss://

所以需要改為setAddress("redis://XXX.XX.XX.X:6379")即可

打印結(jié)果:

org.redisson.Redisson@6159fb3c

二.分布式鎖

1、可重入鎖

基于Redis的Redisson分布式可重入鎖RLock Java對象實現(xiàn)了java.util.concurrent.locks.Lock接口。同時還提供了異步(Async)、反射式(Reactive)和RxJava2標準的接口。

常用代碼:

RLock lock = redisson.getLock("anyLock");
// 最常見的使用方法
lock.lock();

測試代碼:

@ResponseBody
    @GetMapping("/hello")
    public String hello() {
        // 1.獲取一把鎖,只要鎖的名字一樣,就是同一把鎖
        RLock lock = redisson.getLock("my-lock");
        lock.lock(); // 阻塞式等待。默認加的鎖是30s時間
        try {
            // 1、鎖的自動續(xù)期,運行期間自動給鎖續(xù)上新的30s,無需擔心業(yè)務時間長,鎖過期會自動被釋放
            // 2、加鎖的業(yè)務只要運行完成,就不會給當前鎖續(xù)期,即使不手動釋放鎖,鎖默認在30s后自動釋放,避免死鎖
            System.out.println("加鎖成功,執(zhí)行業(yè)務代碼..."+Thread.currentThread().getId());
            Thread.sleep(30000);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            System.out.println("釋放鎖..."+Thread.currentThread().getId());
            lock.unlock();
        }
        return "Hello!";
    }

結(jié)果:

加鎖成功,執(zhí)行業(yè)務代碼...99
釋放鎖...99

可以發(fā)現(xiàn),當我們的業(yè)務超長時,運行期間,redisson會為我們自動續(xù)期鎖,業(yè)務執(zhí)行完將不會續(xù)期,即使不手動釋放鎖,鎖也會默認在30s后釋放。

2、看門狗機制

redisson 中提供的續(xù)期機制

開一個監(jiān)聽線程,如果方法還沒執(zhí)行完,就幫你重置 redis 鎖的過期時間。

原理:

  1. 啟動定時任務重新給鎖設置過期時間,默認過期時間是 30 秒,每 10 秒(看門狗默認事件的1/3)續(xù)期一次(補到 30 秒)
  2. 如果線程掛掉(注意 debug 模式也會被它當成服務器宕機),則不會續(xù)期
  3. 只有l(wèi)ock.lock(); 會有看門狗機制;
  4. lock.lock(10,,TimeUnit.SECONDS);手動設置過期時間的話,則不會有看門狗機制(推薦)

3、讀寫鎖

一次只有一個線程可以占有寫模式的讀寫鎖, 但是可以有多個線程同時占有讀模式的讀寫鎖.(該數(shù)據(jù)加寫鎖、讀數(shù)據(jù)加讀鎖)

  • 當讀寫鎖是寫加鎖狀態(tài)時, 在這個鎖被解鎖之前, 所有試圖對這個鎖加鎖的線程都會被阻塞.
  • 當讀寫鎖在讀加鎖狀態(tài)時, 所有試圖以讀模式對它進行加鎖的線程都可以得到訪問權, 但是如果線程希望以寫模式對此鎖進行加鎖, 它必須直到所有的線程釋放鎖.

測試讀寫鎖代碼:

    
    @Autowired
    RedissonClient redisson;

    @Autowired
    RedisTemplate redisTemplate;

    @ResponseBody
    @GetMapping("/write")
    public String writeValue(){
        RReadWriteLock lock = redisson.getReadWriteLock("rw-lock");
        RLock rLock = lock.writeLock();
        String s = "";
        try {
            s = UUID.randomUUID().toString();
            // 模擬業(yè)務時間    
            Thread.sleep(30000);
        } catch (Exception e){

        }finally {
            rLock.unlock();
        }
        redisTemplate.opsForValue().set("writeValue",s);
        return s;
    }

    @GetMapping(value = "/read")
    @ResponseBody
    public String readValue() {
        String s = "";
        RReadWriteLock readWriteLock = redisson.getReadWriteLock("rw-lock");
        //加讀鎖
        RLock rLock = readWriteLock.readLock();
        try {
            rLock.lock();
            s = (String) redisTemplate.opsForValue().get("writeValue");

            TimeUnit.SECONDS.sleep(10);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            rLock.unlock();
        }
        return s;
    }

當我們訪問 localhost:10000/write寫入數(shù)據(jù)時,因為線程睡眠了30s(模擬業(yè)務),此時我們訪問  localhost:10000/read 將會一直阻塞,等待寫鎖釋放,讀鎖才能占鎖從而獲取執(zhí)行業(yè)務。

4、信號量

信號量為存儲在redis中的一個數(shù)字,當這個數(shù)字大于0時,即可以調(diào)用acquire()方法增加數(shù)量,也可以調(diào)用release()方法減少數(shù)量,但是當調(diào)用release()之后小于0的話方法就會阻塞,直到數(shù)字大于0。 

可以應用于秒殺、限流等操作。

簡單應用

    @GetMapping(value = "/park")
    @ResponseBody
    public String park() {
        RSemaphore park = redisson.getSemaphore("park");
        try {
            park.acquire();// 獲取一個信號量(redis中信號量值-1),如果redis中信號量為0了,則在這里阻塞住,直到信號量大于0,可以拿到信號量,才會繼續(xù)執(zhí)行。
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return "ok";
    }

    @GetMapping(value = "/go")
    @ResponseBody
    public String go() {
        RSemaphore park = redisson.getSemaphore("park");
        park.release();  //釋放一個信號量(redis中信號量值+1)
        return "ok";
    }

其中:redisson.getSemaphore("park").acquire() 當信號量為0時將會一直阻塞,直到信號量大于0,才會繼續(xù)執(zhí)行。但redisson.getSemaphore("park").tryAcquire() 將不會阻塞,能拿到信號量就返回true,否則返回false,lock.tryLock() 同理。

5、閉鎖

在要完成某些運算時,只有其它線程的運算全部運行完畢,當前運算才繼續(xù)下去。

模擬場景:

學校放假,學校門衛(wèi)鎖門必須等待所有班級全部離開,才將學校大門鎖住。

    @GetMapping(value = "/lockDoor")
    @ResponseBody
    public String lockDoor() throws InterruptedException {
        RCountDownLatch lockDoor = redisson.getCountDownLatch("lockDoor");
        lockDoor.trySetCount(5); // 設置計數(shù)為5
        lockDoor.await(); //等待閉鎖完成
        return "放假啦...";
    }

    @GetMapping(value = "/go/{id}")
    public String go(@PathVariable("id") Integer id)  {
        RCountDownLatch lockDoor = redisson.getCountDownLatch("lockDoor");
        lockDoor.countDown(); // 計數(shù)減1
        return id+"班都走光了";
    }

結(jié)果:我們先訪問 /lockDoor 線程將會阻塞,連續(xù)訪問五次 /go/1 ,輸出 放假了。

三.緩存數(shù)據(jù)一致性解決方案

盡量給鎖加上過期時間;對于讀寫狀態(tài)時,應該加上分布式讀寫鎖。

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • Mybatis中typeAliases的使用

    Mybatis中typeAliases的使用

    這篇文章主要介紹了Mybatis中typeAliases的使用,需要的朋友可以參考下
    2017-08-08
  • springboot新建項目pom.xml文件第一行報錯的解決

    springboot新建項目pom.xml文件第一行報錯的解決

    這篇文章主要介紹了springboot新建項目pom.xml文件第一行報錯的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • SpringMVC通過注解實現(xiàn)全局異常處理問題小結(jié)

    SpringMVC通過注解實現(xiàn)全局異常處理問題小結(jié)

    文章介紹SpringMVC全局異常處理機制,通過@ControllerAdvice和@ExceptionHandler注解實現(xiàn)統(tǒng)一異常處理,提升代碼可維護性與響應一致性,減少重復try-catch代碼,增強系統(tǒng)健壯性,本文給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧
    2025-09-09
  • 微信公眾帳號開發(fā)教程之圖文消息全攻略

    微信公眾帳號開發(fā)教程之圖文消息全攻略

    本篇主要介紹微信公眾帳號開發(fā)中圖文消息的使用,以及圖文消息的幾種表現(xiàn)形式。標題取名為"圖文消息全攻略",這絕對不是標題黨,是想借此機會把大家對圖文消息相關的問題、疑慮、障礙全部清除掉。
    2016-12-12
  • Netty之使用DelimiterBasedFrameDecoder進行消息分隔詳解

    Netty之使用DelimiterBasedFrameDecoder進行消息分隔詳解

    這篇文章主要介紹了Netty之使用DelimiterBasedFrameDecoder進行消息分隔詳解,在使用Netty進行TCP消息傳輸時,為了上層協(xié)議能夠?qū)ο⒄_區(qū)分,避免粘包和拆包導致的問題,一般可以通過消息定長、將回車換行符作為消息結(jié)束符,需要的朋友可以參考下
    2023-12-12
  • Java之定時器Timer和定時任務TimerTask應用以及原理解讀

    Java之定時器Timer和定時任務TimerTask應用以及原理解讀

    文章介紹了Java JDK自帶的定時器Timer和定時任務TimerTask的使用和原理,Timer和TimerTask成對出現(xiàn),Timer是定時器,TimerTask是定時任務,TimerTask實現(xiàn)Runnable接口的run方法,Timer的屬性TimerThreadthread繼承Thread
    2024-12-12
  • Mybatis中使用updateBatch進行批量更新

    Mybatis中使用updateBatch進行批量更新

    這篇文章主要介紹了Mybatis中使用updateBatch進行批量更新的相關資料,有逐條更新,sql批量更新等,具體實例代碼大家參考下本文
    2018-04-04
  • springboot內(nèi)嵌Tomcat安全漏洞修復方式

    springboot內(nèi)嵌Tomcat安全漏洞修復方式

    針對CVE-2020-1938漏洞,建議升級Tomcat至安全版本以避免受影響,影響版本包括:Apache Tomcat 9.x小于9.0.31、Apache Tomcat 8.x小于8.5.51、Apache Tomcat 7.x小于7.0.100及Apache Tomcat 6.x,
    2024-10-10
  • Java?ThreadPoolExecutor線程池有關介紹

    Java?ThreadPoolExecutor線程池有關介紹

    這篇文章主要介紹了Java?ThreadPoolExecutor線程池有關介紹,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-09-09
  • java LocalDateTime加時間,計算兩個時間的差方式

    java LocalDateTime加時間,計算兩個時間的差方式

    文章介紹了如何在Java中使用LocalDateTime類添加時間并計算兩個時間的差值,通過比較來總結(jié)個人經(jīng)驗,并鼓勵讀者參考和支持腳本之家
    2025-03-03

最新評論

惠安县| 叙永县| 郸城县| 云南省| 巴南区| 朝阳市| 修水县| 崇信县| 台州市| 洛南县| 东阿县| 龙海市| 清远市| 江油市| 大同市| 包头市| 吉首市| 宁强县| 宝坻区| 通渭县| 小金县| 贺州市| 临湘市| 安陆市| 响水县| 乌兰浩特市| 永修县| 依安县| 阿克苏市| 高平市| 玉田县| 内丘县| 凉山| 六枝特区| 永寿县| 邳州市| 商洛市| 鞍山市| 武功县| 定州市| 康保县|