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

Spring Boot + Redisson 分布式鎖示例案例

 更新時間:2025年12月10日 09:55:37   作者:沃心  
本文提供了一個完整的SpringBoot+Redisson分布式鎖示例項目結構,包括Maven依賴、配置文件、Redisson配置類、業(yè)務服務層和控制器等,通過這個示例,可以實現(xiàn)分布式環(huán)境下的并發(fā)控制,感興趣的朋友一起看看吧

下面為你提供一個完整的 Spring Boot + Redisson 分布式鎖示例項目結構,包含:

  • Maven 依賴配置
  • Redisson 配置類(支持單機/集群)
  • 分布式鎖工具封裝
  • 控制器示例(模擬并發(fā)場景)
  • 測試方法建議

你可以直接復制到你的項目中使用。

?? 項目結構概覽

src/
├── main/
│   ├── java/
│   │   └── com.example.redissonlock/
│   │       ├── RedissonLockApplication.java
│   │       ├── config/
│   │       │   └── RedissonConfig.java
│   │       ├── service/
│   │       │   ├── OrderService.java
│   │       │   └── impl/
│   │       │       └── OrderServiceImpl.java
│   │       └── controller/
│   │           └── OrderController.java
│   └── resources/
│       ├── application.yml
│       └── application-dev.yml (可選)
└── test/
    └── java/
        └── com.example.redissonlock/
            └── RedissonLockTest.java

1?? Maven 依賴(pom.xml)

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.5</version> <!-- 支持 JDK 17+ -->
        <relativePath/>
    </parent>
    <groupId>com.example</groupId>
    <artifactId>redisson-lock-demo</artifactId>
    <version>1.0.0</version>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <!-- Web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- Redisson Starter (自動配置 RedissonClient) -->
        <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson-spring-boot-starter</artifactId>
            <version>3.25.2</version> <!-- 檢查最新版:https://mvnrepository.com/artifact/org.redisson/redisson-spring-boot-starter -->
        </dependency>
        <!-- Lombok (可選,簡化日志/Getter/Setter) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

? 注意redisson-spring-boot-starter 已包含 spring-boot-starter-data-redisredisson 核心包。

2?? 配置文件(application.yml)

spring:
  application:
    name: redisson-lock-demo
  # Redis 連接配置(單機模式)
  redis:
    host: localhost
    port: 6379
    database: 0
    timeout: 2000ms
    lettuce:
      pool:
        max-active: 8
        max-idle: 8
        min-idle: 0
# Redisson 自定義配置(可選,如需調(diào)整看門狗等)
# 如果不配置,Redisson 會自動使用 spring.redis 下的連接信息

?? 集群模式示例(替換 spring.redis):

spring:
  redis:
    cluster:
      nodes:
        - 192.168.1.10:7000
        - 192.168.1.10:7001
        - 192.168.1.10:7002
    password: your_password
    timeout: 2000ms

3?? Redisson 配置類(可選,用于自定義)

?? 如果只用單機 Redis,其實不需要寫這個類!redisson-spring-boot-starter 會自動創(chuàng)建 RedissonClient。
但如果你需要自定義(如修改看門狗超時、啟用 codec),可以添加:

// src/main/java/com/example/redissonlock/config/RedissonConfig.java
package com.example.redissonlock.config;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RedissonConfig {
    @Value("${spring.redis.host}")
    private String redisHost;
    @Value("${spring.redis.port}")
    private int redisPort;
    @Bean(destroyMethod = "shutdown")
    public RedissonClient redissonClient() {
        Config config = new Config();
        config.useSingleServer()
              .setAddress("redis://" + redisHost + ":" + redisPort)
              .setTimeout(3000)
              .setConnectionPoolSize(10);
        // 可選:調(diào)整看門狗超時(默認30秒)
        // config.setLockWatchdogTimeout(60000); // 60秒
        return Redisson.create(config);
    }
}

4?? 業(yè)務服務層(帶分布式鎖)

// src/main/java/com/example/redissonlock/service/OrderService.java
package com.example.redissonlock.service;
public interface OrderService {
    void createOrder(String userId, String orderId);
}
// src/main/java/com/example/redissonlock/service/impl/OrderServiceImpl.java
package com.example.redissonlock.service.impl;
import com.example.redissonlock.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;
@Slf4j
@Service
public class OrderServiceImpl implements OrderService {
    private final RedissonClient redissonClient;
    public OrderServiceImpl(RedissonClient redissonClient) {
        this.redissonClient = redissonClient;
    }
    @Override
    public void createOrder(String userId, String orderId) {
        // 鎖 key 建議包含業(yè)務唯一標識,避免全局鎖
        String lockKey = "order:create:" + orderId;
        RLock lock = redissonClient.getLock(lockKey);
        try {
            // 嘗試加鎖:最多等待 3 秒,持有鎖 30 秒(看門狗會自動續(xù)期)
            boolean isLocked = lock.tryLock(3, 30, TimeUnit.SECONDS);
            if (!isLocked) {
                log.warn("獲取分布式鎖失敗,orderId={}", orderId);
                throw new RuntimeException("系統(tǒng)繁忙,請稍后再試");
            }
            log.info("線程 {} 獲取鎖成功,開始處理訂單 {}", Thread.currentThread().getName(), orderId);
            // 模擬業(yè)務耗時(即使超過30秒也不會丟鎖?。?
            Thread.sleep(5000);
            // TODO: 真實業(yè)務邏輯(如扣庫存、寫DB)
            log.info("訂單 {} 創(chuàng)建成功", orderId);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            log.error("訂單處理被中斷", e);
            throw new RuntimeException(e);
        } finally {
            // 安全釋放鎖(Redisson 會校驗線程ID)
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
                log.info("線程 {} 釋放鎖,orderId={}", Thread.currentThread().getName(), orderId);
            }
        }
    }
}

5?? 控制器(用于測試)

// src/main/java/com/example/redissonlock/controller/OrderController.java
package com.example.redissonlock.controller;
import com.example.redissonlock.service.OrderService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequiredArgsConstructor
public class OrderController {
    private final OrderService orderService;
    @GetMapping("/create-order")
    public String createOrder(@RequestParam String userId,
                              @RequestParam String orderId) {
        orderService.createOrder(userId, orderId);
        return "Order created: " + orderId;
    }
}

6?? 啟動類

// src/main/java/com/example/redissonlock/RedissonLockApplication.java
package com.example.redissonlock;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class RedissonLockApplication {
    public static void main(String[] args) {
        SpringApplication.run(RedissonLockApplication.class, args);
    }
}

?? 如何測試并發(fā)效果?

方法 1:使用 JMeter / Postman Runner

  • 發(fā)起多個并發(fā)請求到:
    GET http://localhost:8080/create-order?userId=U1&orderId=O1001
  • 觀察日志:同一 orderId 的請求會串行執(zhí)行

方法 2:單元測試(模擬多線程)

// src/test/java/com/example/redissonlock/RedissonLockTest.java
@Test
void testConcurrentOrderCreation() throws InterruptedException {
    ExecutorService executor = Executors.newFixedThreadPool(5);
    CountDownLatch latch = new CountDownLatch(5);
    for (int i = 0; i < 5; i++) {
        executor.submit(() -> {
            try {
                orderService.createOrder("U1", "O1001"); // 相同 orderId
            } finally {
                latch.countDown();
            }
        });
    }
    latch.await(); // 等待所有線程完成
    executor.shutdown();
}

? 關鍵優(yōu)勢總結

特性說明
自動續(xù)期Watchdog 默認每 10s 續(xù)期一次,不怕業(yè)務超時
安全釋放基于線程 ID 校驗,不會誤刪其他線程的鎖
可重入同一線程可多次加鎖
無死鎖風險即使應用 crash,鎖也會在 watchdog 超時后釋放
Spring Boot 集成簡單starter 自動配置,開箱即用

?? 注意事項

  1. 鎖 key 設計:務必帶上業(yè)務唯一標識(如 order:{orderId}),避免鎖粒度太大。
  2. 不要在鎖內(nèi)做遠程調(diào)用:如 HTTP 請求、MQ 發(fā)送,可能因網(wǎng)絡延遲導致鎖持有時間過長。
  3. 監(jiān)控鎖狀態(tài):可通過 Redis CLI 查看:KEYS *order*、TTL your_lock_key
  4. 生產(chǎn)環(huán)境 Redis 高可用:建議使用 Redis Cluster 或 Sentinel。

到此這篇關于完整的 Spring Boot + Redisson 分布式鎖示例的文章就介紹到這了,更多相關Spring Boot Redisson 分布式鎖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • SpringBoot基于docx4j實現(xiàn)DOCX轉PDF的具體方案

    SpringBoot基于docx4j實現(xiàn)DOCX轉PDF的具體方案

    在日常項目開發(fā)中,我們經(jīng)常遇到用戶上傳 Word( .docx)文件,希望后臺自動生成 PDF,用于下載、歸檔或在線預覽,本文將介紹一個完全開源、部署簡單、純 Java 的實現(xiàn)方案,感興趣的小伙伴可以跟著小編一起來看看
    2025-11-11
  • java:程序包org.apache.ibatis.annotations不存在報錯解決

    java:程序包org.apache.ibatis.annotations不存在報錯解決

    這篇文章主要給大家介紹了關于java:程序包org.apache.ibatis.annotations不存在報錯的解決方法,這個錯誤是我在直接導入springboot項目的時候報錯的,文中通過圖文介紹的非常詳細,需要的朋友可以參考下
    2023-04-04
  • mybatis的mapper對應的xml寫法及配置詳解

    mybatis的mapper對應的xml寫法及配置詳解

    這篇文章給大家介紹mybatis的mapper對應的xml寫法及配置詳解,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2025-05-05
  • Java集合Stack源碼詳解

    Java集合Stack源碼詳解

    java工具包中的Stack是繼承于Vector(矢量隊列)的,由于Vector是通過數(shù)組實現(xiàn)的,這就意味著,Stack也是通過數(shù)組實現(xiàn)的,而非鏈表。當然,我們也可以將LinkedList當作棧來使用!
    2018-05-05
  • java虛擬機中多線程總結

    java虛擬機中多線程總結

    在本篇內(nèi)容中小編給大家分享的是關于java虛擬機中多線程的知識點總結內(nèi)容,需要的朋友們參考學習下。
    2019-06-06
  • 深入解析面向?qū)ο缶幊淘贘ava中的應用小結

    深入解析面向?qū)ο缶幊淘贘ava中的應用小結

    本文詳細介紹了面向?qū)ο缶幊痰幕靖拍?包括類和對象、封裝、繼承和多態(tài),通過具體的Java代碼示例,展示了如何在Java中應用這些面向?qū)ο缶幊痰暮诵乃枷?感興趣的朋友跟隨小編一起看看吧
    2025-01-01
  • SpringBoot實現(xiàn)簡單的登錄注冊的項目實戰(zhàn)

    SpringBoot實現(xiàn)簡單的登錄注冊的項目實戰(zhàn)

    本文主要介紹了SpringBoot實現(xiàn)簡單的登錄注冊的項目實戰(zhàn),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • 詳解java中finalize的實現(xiàn)與相應的執(zhí)行過程

    詳解java中finalize的實現(xiàn)與相應的執(zhí)行過程

    在常規(guī)的java書籍中,即會描述 object的finalize方法是用于一些特殊的對象在回收之前再做一些掃尾的工作,但是并沒有說明此是如何實現(xiàn)的.本篇從java的角度(不涉及jvm以及c++),有需要的朋友們可以參考借鑒。
    2016-09-09
  • Java 程序初始化順序

    Java 程序初始化順序

    這篇文章主要介紹了Java 程序初始化順序,在Java語言中,當實例化對象時,對象所在類的所有成員變量首先要進行初始化,只有當所有的類成員完成了初始化之后,才會調(diào)用對象所在類的構造函數(shù)創(chuàng)建對象,需要的朋友可以參考一下
    2022-01-01
  • Java實現(xiàn)一個簡單的長輪詢的示例代碼

    Java實現(xiàn)一個簡單的長輪詢的示例代碼

    長輪詢是與服務器保持即時通信的最簡單的方式,它不使用任何特定的協(xié)議,例如 WebSocket ,所以也不依賴于瀏覽器版本等外部條件的兼容性。本文將用Java實現(xiàn)一個簡單的長輪詢,需要的可以參考一下
    2022-08-08

最新評論

涿鹿县| 巴东县| 达尔| 英吉沙县| 囊谦县| 遂平县| 喀喇沁旗| 招远市| 龙海市| 南充市| 绿春县| 瑞丽市| 襄樊市| 吉首市| 凌海市| 高清| 吐鲁番市| 大厂| 丰台区| 黔江区| 梧州市| 贺州市| 洪雅县| 洛阳市| 沂源县| 岚皋县| 玉树县| 资阳市| 和平县| 玛沁县| 屏边| 湘潭市| 延川县| 周宁县| 仁布县| 海宁市| 威信县| 娱乐| 卢湾区| 兖州市| 隆尧县|