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

redis哨兵模式分布式鎖實(shí)現(xiàn)與實(shí)踐方式(redisson)

 更新時(shí)間:2024年03月05日 14:38:32   作者:喵喵@香菜  
這篇文章主要介紹了redis哨兵模式分布式鎖實(shí)現(xiàn)與實(shí)踐方式(redisson),具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

一、前言

在某個(gè)線程操作數(shù)據(jù)庫(kù)中的某條數(shù)據(jù)時(shí),我們需要確保當(dāng)前時(shí)刻只有一個(gè)線程在操作這條記錄,如果有兩個(gè)線程競(jìng)爭(zhēng)同一個(gè)數(shù)據(jù),就需要在考慮先后執(zhí)行順序以后,那么怎樣在一個(gè)線程拿到這條數(shù)據(jù)時(shí),阻塞其他線程操作呢?

分布式鎖就可以解決上述難題。

以下演示是利用分布式鎖,確保同一時(shí)間只有一個(gè)線程在操作數(shù)據(jù)庫(kù),阻塞其他線程。

環(huán)境:

  • redis(哨兵模式)
  • spring boot

二、redis的配置(注意是哨兵模式)

1)依賴

<?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 https://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>2.2.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.zlc</groupId>
    <artifactId>distributedlock-a</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>distributedlock-a</name>
    <description>分布式鎖(哨兵模式)</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

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

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson</artifactId>
            <version>3.3.2</version>
        </dependency>
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

2)redis配置

server:
  port: 8081
spring:
  redis:
    sentinel:
      master: testmaster
      nodes: 127.0.0.1:26379,127.0.0.1:36379,127.0.0.1:16379
    timeout: 3000          # 超時(shí)時(shí)間(數(shù)據(jù)處理超時(shí)時(shí)間,不是連接超時(shí)時(shí)間)
    lettuce:
      pool:
        max-active: 200     #連接池最大連接數(shù)(使用負(fù)值表示沒(méi)有限制)
        max-idle: 20        #連接池中的最大空閑連接
        min-idle: 5         #連接池中的最小空閑連接
        max-wait: -1        #連接池最大阻塞等待時(shí)間(使用負(fù)值表示沒(méi)有限制)
    password: 123456        #redis 密碼
    database: 1             # 使用的是庫(kù)1,如果不配置,則使用默認(rèn)的0

三、代碼實(shí)戰(zhàn)

根據(jù)上面的配置文件,將redis的各個(gè)配置轉(zhuǎn)換為實(shí)體對(duì)象

1)sentinel 節(jié)點(diǎn)

package com.zlc.distributedlocka.model.redis;

import lombok.Data;
import lombok.ToString;

/**
 * @author : 追到烏云的盡頭找太陽(yáng)-(Jacob)
 * @date : 2020/1/20 11:13
 **/
@Data
@ToString
public class RedisSentinelModel {
    
    private String master;

    private String nodes;
}

2)pool節(jié)點(diǎn)

package com.zlc.distributedlocka.model.redis;

import lombok.Data;
import lombok.ToString;

/**
 * @author : 追到烏云的盡頭找太陽(yáng)-(Jacob)
 * @date : 2020/1/20 11:16
 **/
@Data
@ToString
public class RedisPoolModel {

    private int maxIdle;

    private int minIdle;

    private int maxActive;

    private int maxWait;
    
}

3)Lettuce 節(jié)點(diǎn)

package com.zlc.distributedlocka.model.redis;

import lombok.Data;

/**
 * @author : 追到烏云的盡頭找太陽(yáng)-(Jacob)
 * @date : 2020/1/20 11:18
 **/
@Data
public class RedisLettuceConfig {
    
    private RedisPoolModel redisPoolModel;
    
}

4)redis

package com.zlc.distributedlocka.model.redis;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

/**
 * @author : 追到烏云的盡頭找太陽(yáng)-(Jacob)
 * @date : 2020/1/20 11:21
 **/
@Data
@Configuration
@ConfigurationProperties(prefix = "spring.redis")
public class RedisModel {

    private int database;
    /**
     * 等待節(jié)點(diǎn)回復(fù)命令的時(shí)間。該時(shí)間從命令發(fā)送成功時(shí)開(kāi)始計(jì)時(shí)
     **/
    private int timeout;

    private String password;

    /**
     * 池配置
     */
    private RedisLettuceModel lettuce;

    /**
     * 哨兵配置
     */
    private RedisSentinelModel sentinel;
}

5)redisson

package com.zlc.distributedlocka.config;

import com.zlc.distributedlocka.model.redis.RedisModel;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.config.ReadMode;
import org.redisson.config.SentinelServersConfig;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @author : 追到烏云的盡頭找太陽(yáng)-(Jacob)
 * @date : 2020/1/20 11:27
 **/
@Configuration
@EnableConfigurationProperties(RedisModel.class)
public class RedissonConfig {

    private final RedisModel redisModel;
    
    public RedissonConfig(RedisModel redisModel) {
        this.redisModel = redisModel;
    }

    @Bean
    public RedissonClient redissonClient(){
        Config config = new Config();
        String [] nodes = redisModel.getSentinel().getNodes().split(",");
        List<String> newNodes = new ArrayList<>(nodes.length);
        newNodes.addAll(Arrays.asList(nodes));

        SentinelServersConfig serverConfig = config.useSentinelServers()
                .addSentinelAddress(newNodes.toArray(new String[0]))
                .setMasterName(redisModel.getSentinel().getMaster())
                .setReadMode(ReadMode.SLAVE)
                .setTimeout(redisModel.getTimeout());
        // 設(shè)置密碼
        if(StringUtils.isNotBlank(redisModel.getPassword())){
            serverConfig.setPassword(redisModel.getPassword());
        }
        // 設(shè)置database
        if (redisModel.getDatabase()!=0){
            serverConfig.setDatabase(redisModel.getDatabase());
        }
        return Redisson.create(config);
    }
}

四、使用

一個(gè)簡(jiǎn)單的使用方法示例

package com.zlc.distributedlocka;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import java.util.concurrent.TimeUnit;

@SpringBootApplication
public class DistributedlockAApplication {
    
    @Autowired
    private RedissonClient redissonClient;

    public static void main(String[] args) {
        SpringApplication.run(DistributedlockAApplication.class, args);
    }
    
    // 這里的鎖是對(duì)哨兵模式下的database生效的,
    // 需要分布式鎖的兩個(gè)系統(tǒng)一定要使用同一哨兵模式的database
    // 如果一個(gè)使用默認(rèn)0,一個(gè)使用1或者其他,是鎖不住的
    private void TestLock(){
        boolean lockFlag = false;
        RLock rLock = null;
        try {
            // 使用redis中的某個(gè)key值作為獲取分布式鎖
            rLock = redissonClient.getLock("redisKey");
            //  第一個(gè)參數(shù)為等待時(shí)間,第二個(gè)參數(shù)為占有時(shí)間(單位都為毫秒)
            // 等待時(shí)間為如果沒(méi)有通過(guò)redisKey獲取到鎖,則等待1s,1s后還沒(méi)獲取到鎖,則tryLock返回false,表明有人正在使用
            // 如果直接獲取到鎖了,則表明沒(méi)有人使用,設(shè)置了你占有他的時(shí)間為5s
            lockFlag = rLock.tryLock(1000, 5000, TimeUnit.MILLISECONDS);
            if (lockFlag){
                // 獲取到鎖,進(jìn)行數(shù)據(jù)處理或者其他操作
            }else {
                // 沒(méi)有獲取到鎖,進(jìn)行一些操作
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            // 如果鎖沒(méi)有釋放,手動(dòng)釋放鎖
            // 注意是使用isHeldByCurrentThread
            if (lockFlag && rLock.isHeldByCurrentThread()){
                rLock.unlock();
            }
        }
    }
}

總結(jié)

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

相關(guān)文章

  • Redis大量數(shù)據(jù)插入過(guò)程

    Redis大量數(shù)據(jù)插入過(guò)程

    本文介紹Redis處理大數(shù)據(jù)插入的三種高效方法:redis-cli管道模式、Jedis pipelined()方法及RedisTemplate批量保存,旨在減少通信開(kāi)銷并提升吞吐量
    2025-08-08
  • Redis配置文件最佳實(shí)踐

    Redis配置文件最佳實(shí)踐

    這篇文章主要介紹了Redis配置文件詳解,本文主要是根據(jù)Redis6.0.x版本的配置文件講解,其它版本的也可以當(dāng)做一個(gè)參考,需要的朋友可以參考下
    2025-05-05
  • 一文帶你了解Redis中RDB與AOF的區(qū)別

    一文帶你了解Redis中RDB與AOF的區(qū)別

    Redis 在持久化時(shí),給我們提供了兩種方式,這兩種方式就是 RDB 與 AOF,那這兩種方式有什么區(qū)別呢,本文就帶大家詳細(xì)的了解一下二者的區(qū)別,需要的朋友可以參考下
    2023-06-06
  • SpringBoot整合Mybatis-plus和Redis實(shí)現(xiàn)投票功能

    SpringBoot整合Mybatis-plus和Redis實(shí)現(xiàn)投票功能

    投票功能是一個(gè)非常常見(jiàn)的Web應(yīng)用場(chǎng)景,這篇文章將為大家介紹一下如何將Redis和Mybatis-plus整合到SpringBoot中,實(shí)現(xiàn)投票功能,感興趣的可以了解一下
    2023-05-05
  • redis實(shí)現(xiàn)延遲任務(wù)的項(xiàng)目實(shí)踐

    redis實(shí)現(xiàn)延遲任務(wù)的項(xiàng)目實(shí)踐

    本文主要介紹了redis實(shí)現(xiàn)延遲任務(wù)的項(xiàng)目實(shí)踐,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • Redis服務(wù)之高可用組件sentinel詳解

    Redis服務(wù)之高可用組件sentinel詳解

    這篇文章主要介紹了Redis服務(wù)之高可用組件sentinel,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-08-08
  • Redis Cluster集群主從切換的踩坑與填坑

    Redis Cluster集群主從切換的踩坑與填坑

    這篇文章主要介紹了Redis Cluster集群主從切換的踩坑與填坑,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-04-04
  • Redis中的BigKey問(wèn)題排查與解決思路詳解

    Redis中的BigKey問(wèn)題排查與解決思路詳解

    Redis是一款性能強(qiáng)勁的內(nèi)存數(shù)據(jù)庫(kù),但是在使用過(guò)程中,我們可能會(huì)遇到Big Key問(wèn)題,這個(gè)問(wèn)題就是Redis中某個(gè)key的value過(guò)大,所以Big Key問(wèn)題本質(zhì)是Big Value問(wèn)題,這篇文章主要介紹了Redis中的BigKey問(wèn)題:排查與解決思路,需要的朋友可以參考下
    2023-03-03
  • Windows系統(tǒng)安裝redis數(shù)據(jù)庫(kù)

    Windows系統(tǒng)安裝redis數(shù)據(jù)庫(kù)

    這篇文章介紹了Windows系統(tǒng)安裝redis數(shù)據(jù)庫(kù)的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-03-03
  • 詳解redis集群選舉機(jī)制

    詳解redis集群選舉機(jī)制

    這篇文章主要介紹了詳解redis集群選舉機(jī)制,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03

最新評(píng)論

沂源县| 马鞍山市| 罗源县| 陵川县| 平江县| 杭锦旗| 松潘县| 卓尼县| 蕲春县| 浦县| 堆龙德庆县| 博野县| 丽水市| 汝南县| 杂多县| 渭南市| 环江| 都安| 合水县| 策勒县| 靖边县| 兴和县| 玉门市| 丹棱县| 沈丘县| 富阳市| 太原市| 黄陵县| 贡觉县| 信丰县| 二手房| 东源县| 依安县| 边坝县| 绩溪县| 柞水县| 万载县| 甘德县| 南京市| 秦安县| 象山县|