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

Redis使用SETNX命令實(shí)現(xiàn)分布式鎖

 更新時(shí)間:2025年01月16日 08:20:06   作者:ppo92  
分布式鎖是一種用于在分布式系統(tǒng)中控制多個(gè)節(jié)點(diǎn)對(duì)共享資源進(jìn)行訪問的機(jī)制,本文主要為大家詳細(xì)介紹了Redis如何使用SETNX命令實(shí)現(xiàn)分布式鎖,需要的可以參考下

什么是分布式鎖

分布式鎖是一種用于在分布式系統(tǒng)中控制多個(gè)節(jié)點(diǎn)對(duì)共享資源進(jìn)行訪問的機(jī)制。在分布式系統(tǒng)中,由于多個(gè)節(jié)點(diǎn)可能同時(shí)訪問和修改同一個(gè)資源,因此需要一種方法來確保在任意時(shí)刻只有一個(gè)節(jié)點(diǎn)能夠?qū)Y源進(jìn)行操作,以避免數(shù)據(jù)不一致或沖突。分布式鎖就是用來實(shí)現(xiàn)這種互斥訪問的工具。

為什么 Redis 的 SETNX 可以實(shí)現(xiàn)分布式鎖

Redis 的 SETNX 命令(即 SET if Not eXists)可以用來實(shí)現(xiàn)分布式鎖,原因如下:

  • 原子性SETNX 是一個(gè)原子操作,這意味著在同一時(shí)間只有一個(gè)客戶端能夠成功設(shè)置鍵值對(duì)。如果鍵已經(jīng)存在,SETNX 將不會(huì)執(zhí)行任何操作。這種原子性確保了鎖的獲取和釋放是線程安全的。
  • 唯一性SETNX 確保了鎖的唯一性。只有第一個(gè)嘗試設(shè)置鍵的客戶端能夠成功,其他客戶端在嘗試設(shè)置相同的鍵時(shí)會(huì)失敗。這模擬了鎖的“獲取”和“釋放”行為。
  • 過期時(shí)間:通過結(jié)合 EXPIRE 命令或使用 SET 命令的 EX 選項(xiàng),可以為鎖設(shè)置一個(gè)過期時(shí)間。這防止了鎖被永久占用,即使客戶端在持有鎖期間崩潰或未能正確釋放鎖。
  • 分布式環(huán)境:Redis 是一個(gè)分布式內(nèi)存數(shù)據(jù)庫,可以在多個(gè)節(jié)點(diǎn)之間共享數(shù)據(jù)。因此,使用 Redis 實(shí)現(xiàn)的鎖可以在分布式系統(tǒng)中的多個(gè)節(jié)點(diǎn)之間共享,從而實(shí)現(xiàn)分布式鎖。
  • 高性能:Redis 是一個(gè)高性能的數(shù)據(jù)庫,能夠處理大量的并發(fā)請(qǐng)求。這使得 Redis 非常適合作為分布式鎖的實(shí)現(xiàn)基礎(chǔ)。

準(zhǔn)備工作

創(chuàng)建一個(gè)Spring Boot項(xiàng)目,并引入相關(guān)依賴

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

application.yml文件中配置 Redis 連接信息:

server:
  port: 8080
spring:
  redis:
    host: xxx.xxx.xxx.xxx
    port: 6379
    password: xxxxxx

具體實(shí)現(xiàn)

創(chuàng)建分布式鎖工具類

import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

@Component
public class DistributedLock {

    private final StringRedisTemplate redisTemplate;

    // 通過構(gòu)造函數(shù)注入 StringRedisTemplate
    public DistributedLock(StringRedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    /**
     * 嘗試獲取分布式鎖
     *
     * @param lockKey    鎖的鍵
     * @param requestId  請(qǐng)求標(biāo)識(shí),用于區(qū)分不同的鎖持有者
     * @param expireTime 鎖的過期時(shí)間,單位為毫秒
     * @return 如果成功獲取鎖,返回 true;否則返回 false
     */
    public boolean acquireLock(String lockKey, String requestId, long expireTime) {
        // 使用 setIfAbsent 方法嘗試設(shè)置鍵值對(duì),如果鍵不存在則設(shè)置成功并返回 true,否則返回 false
        Boolean result = redisTemplate.opsForValue().setIfAbsent(lockKey, requestId, expireTime, TimeUnit.MILLISECONDS);
        return result != null && result;
    }

    /**
     * 釋放分布式鎖
     *
     * @param lockKey   鎖的鍵
     * @param requestId 請(qǐng)求標(biāo)識(shí),用于確保只有鎖的持有者才能釋放鎖
     * @return 如果成功釋放鎖,返回 true;否則返回 false
     */
    public boolean releaseLock(String lockKey, String requestId) {
        // 獲取當(dāng)前鎖的值
        String currentValue = redisTemplate.opsForValue().get(lockKey);
        // 檢查當(dāng)前鎖的值是否等于請(qǐng)求標(biāo)識(shí),確保只有鎖的持有者才能釋放鎖
        if (currentValue != null && currentValue.equals(requestId)) {
            // 刪除鎖鍵
            return redisTemplate.delete(lockKey);
        }
        return false;
    }
}

創(chuàng)建業(yè)務(wù)類用來測(cè)試

import com.wh.demo01.demos.web.utils.DistributedLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;

@Service
public class MyRedisService {

    private final DistributedLock distributedLock;

    // 通過構(gòu)造函數(shù)注入 DistributedLock
    @Autowired
    public MyRedisService(DistributedLock distributedLock) {
        this.distributedLock = distributedLock;
    }

    /**
     * 模擬需要同步執(zhí)行的方法
     */
    public void someMethod() {
        String lockKey = "myLockKey";
        String requestId = "uniqueRequestId";
        long expireTime = 10000; // 10 seconds

        try {
            // 嘗試獲取鎖
            if (distributedLock.acquireLock(lockKey, requestId, expireTime)) {
                // 獲取到鎖,執(zhí)行需要同步的操作
                System.out.println(new Date() + "獲取鎖成功");
                // 模擬業(yè)務(wù)操作
                Thread.sleep(5000);
            } else {
                System.out.println(new Date() + "獲取鎖失敗");
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            // 確保鎖在操作完成后被釋放
            distributedLock.releaseLock(lockKey, requestId);
        }
    }
}

創(chuàng)建Controller

import com.wh.demo01.demos.web.service.MyRedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/redis")
public class RedisController {

    @Autowired
    private MyRedisService service;

    @GetMapping("/test")
    public void TestRedis(){
        service.someMethod();
    }
}

整個(gè)項(xiàng)目結(jié)構(gòu)如下:

使用idea的復(fù)制配置功能將該服務(wù)復(fù)制一份,并指定端口為8081,模擬分布式服務(wù):

使用接口調(diào)試工具分別向80808081端口發(fā)送請(qǐng)求:

結(jié)果如下:

可見在分布式鎖的影響下,someMethod方法在10秒內(nèi)只能被調(diào)用一次。

到此這篇關(guān)于Redis使用SETNX命令實(shí)現(xiàn)分布式鎖的文章就介紹到這了,更多相關(guān)Redis SETNX實(shí)現(xiàn)分布式鎖內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 淺析PHP分布式中Redis實(shí)現(xiàn)Session的方法

    淺析PHP分布式中Redis實(shí)現(xiàn)Session的方法

    這篇文章主要介紹了PHP分布式中Redis實(shí)現(xiàn)Session的方法,文中詳細(xì)介紹了兩種方法的使用方法,并給出了測(cè)試的示例代碼,有需要的朋友可以參考借鑒,下面來一起看看吧,
    2016-12-12
  • Redis從基礎(chǔ)到Stream消息隊(duì)列實(shí)戰(zhàn)指南

    Redis從基礎(chǔ)到Stream消息隊(duì)列實(shí)戰(zhàn)指南

    Redis是一個(gè)高性能內(nèi)存數(shù)據(jù)庫,支持字符串、哈希、列表等數(shù)據(jù)結(jié)構(gòu),5.0版本新增Stream類型,提供消息隊(duì)列功能,支持消費(fèi)者組和消息確認(rèn),本文介紹Redis從基礎(chǔ)到Stream消息隊(duì)列實(shí)戰(zhàn)指南,感興趣的朋友跟隨小編一起看看吧
    2026-03-03
  • Redis?持久化原理分析和使用建議詳解

    Redis?持久化原理分析和使用建議詳解

    本文主要介紹了Redis提供的三大持久化機(jī)制,即AOF日志、RDB快照以及混合持久化機(jī)制,結(jié)合圖文實(shí)例給大家講解的非常詳細(xì),感興趣的朋友一起看看吧
    2025-02-02
  • 基于Redis的限流器的實(shí)現(xiàn)(示例講解)

    基于Redis的限流器的實(shí)現(xiàn)(示例講解)

    下面小編就為大家分享一篇基于Redis的限流器的實(shí)現(xiàn)(示例講解),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2017-12-12
  • Redis實(shí)現(xiàn)分布式鎖方法詳細(xì)

    Redis實(shí)現(xiàn)分布式鎖方法詳細(xì)

    在單體應(yīng)用中,如果我們對(duì)共享數(shù)據(jù)不進(jìn)行加鎖操作,會(huì)出現(xiàn)數(shù)據(jù)一致性問題,我們的解決辦法通常是加鎖。在分布式架構(gòu)中,我們同樣會(huì)遇到數(shù)據(jù)共享操作問題。本文將介紹Redis實(shí)現(xiàn)分布式鎖的五種方式。需要的可以參考一下
    2021-12-12
  • redis發(fā)布訂閱_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    redis發(fā)布訂閱_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    這篇文章主要介紹了redis發(fā)布訂閱,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-08-08
  • 緩存替換策略及應(yīng)用(以Redis、InnoDB為例)

    緩存替換策略及應(yīng)用(以Redis、InnoDB為例)

    本文以Redis、InnoDB為例給大家講解緩存替換策略及應(yīng)用,本文給大家提到五種置換策略,通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2021-07-07
  • Redis分布式鎖的實(shí)現(xiàn)方式(redis面試題)

    Redis分布式鎖的實(shí)現(xiàn)方式(redis面試題)

    這篇文章主要介紹了Redis分布式鎖的實(shí)現(xiàn)方式(面試常見),需要的朋友可以參考下
    2020-01-01
  • Redis Cluster 集群搭建你會(huì)嗎

    Redis Cluster 集群搭建你會(huì)嗎

    這篇文章主要介紹了Redis Cluster 集群搭建過程,本文分步驟通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-08-08
  • 解讀緩存db redis local的取舍之道

    解讀緩存db redis local的取舍之道

    這篇文章主要介紹了解讀緩存db redis local的取舍之道,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-05-05

最新評(píng)論

仙居县| 石阡县| 秭归县| 土默特左旗| 邹平县| 綦江县| 来安县| 长阳| 清流县| 寿阳县| 遵义县| 禹城市| 广汉市| 青龙| 台东县| 汝阳县| 桂阳县| 清流县| 托克逊县| 巢湖市| 绩溪县| 昆明市| 桑植县| 六枝特区| 平潭县| 枞阳县| 左贡县| 突泉县| 顺昌县| 桐城市| 黑河市| 视频| 工布江达县| 措勤县| 古浪县| 青铜峡市| 玉田县| 太湖县| 嵩明县| 贵港市| 获嘉县|