SpringBoot 2.0集成Redisson實現分布式鎖(redis-cluster集群模式 與 單機模式)


一般提及到Redis的分布式鎖我們更多的使用的是Redisson的分布式鎖,Redis的官方也是建議我們這樣去做的。Redisson點我可以直接跳轉到Redisson的官方文檔。

 

Redisson概述

 
 

Redisson是一個在Redis的基礎上實現的Java駐內存數據網格(In-Memory Data Grid)。它不僅提供了一系列的分布式的Java常用對象,還提供了許多分布式服務。其中包括(BitSet, Set, Multimap, SortedSet, Map, List, Queue, BlockingQueue, Deque, BlockingDeque, Semaphore, Lock, AtomicLong, CountDownLatch, Publish / Subscribe, Bloom filter, Remote service, Spring cache, Executor service, Live Object service, Scheduler service) Redisson提供了使用Redis的最簡單和最便捷的方法。Redisson的宗旨是促進使用者對Redis的關注分離(Separation of Concern),從而讓使用者能夠將精力更集中地放在處理業務邏輯上。

關於Redisson項目的詳細介紹可以在官方網站找到。

每個Redis服務實例都能管理多達1TB的內存。

能夠完美的在雲計算環境里使用,並且支持AWS ElastiCache主備版AWS ElastiCache集群版Azure Redis Cache阿里雲(Aliyun)的雲數據庫Redis版

以下是Redisson的結構:

Redisson作為獨立節點 可以用於獨立執行其他節點發布到分布式執行服務 和 分布式調度任務服務 里的遠程任務。

 
 

如果你現在正在使用其他的Redis的Java客戶端,那么Redis命令和Redisson對象匹配列表 能夠幫助你輕松的將現有代碼遷徙到Redisson框架里來。

Redisson底層采用的是Netty 框架。支持Redis 2.8以上版本,支持Java1.6+以上版本。

1、引入Maven依賴

<!-- https://mvnrepository.com/artifact/org.redisson/redisson -->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.12.2</version>
</dependency>

 

2、配置redis信息

單機模式

spring:
  redis:
    port: 6379
    host: 127.0.0.1
    password: ******
    database: 0
    timeout: 2000

 

集成模式:

spring:
  redis:
    cluster:
      nodes: "192.168.1.11:7000,192.168.1.12:7000,192.168.1.12:7001"
    password: ******
    lettuce:
      pool:
        max-active: 1500
        max-wait: 5000
        max-idle: 500
        min-idle: 100
        shutdown-timeout: 1000
    timeout: 60000

3、增加一個RedisConfigProperties用於讀取配置文件信息

單機模式

/**
 * redisson 配置類
 * Created on 2018/6/19
 */
@Configuration
public class RedissonConfig {
    @Value("${spring.redis.host}")
    private String host;
@Value(
"${spring.redis.port}") private String port;
@Value(
"${spring.redis.password}") private String password; @Bean public RedissonClient getRedisson(){ Config config = new Config(); config.useSingleServer().setAddress("redis://" + host + ":" + port).setPassword(password); //添加主從配置 // config.useMasterSlaveServers().setMasterAddress("").setPassword("").addSlaveAddress(new String[]{"",""}); return Redisson.create(config); } }

 

集成模式

@Component
@ConfigurationProperties(prefix = "spring.redis")
public class RedisConfigProperties {
    private String password;
    private cluster cluster;

    public static class cluster {
        private List<String> nodes;

        public List<String> getNodes() {
            return nodes;
        }

        public void setNodes(List<String> nodes) {
            this.nodes = nodes;
        }
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public RedisConfigProperties.cluster getCluster() {
        return cluster;
    }

    public void setCluster(RedisConfigProperties.cluster cluster) {
        this.cluster = cluster;
    }
}

 

@Configuration
public class RedissonConfig {
    @Autowired
    private RedisConfigProperties redisConfigProperties;

    @Bean
    public RedissonClient redissonClient() {
        //redisson版本是3.5,集群的ip前面要加上“redis://”,不然會報錯,3.2版本可不加
        List<String> clusterNodes = new ArrayList<>();
        for (int i = 0; i < redisConfigProperties.getCluster().getNodes().size(); i++) {
            clusterNodes.add("redis://" + redisConfigProperties.getCluster().getNodes().get(i));
        }
        Config config = new Config();
        // 添加集群地址
        ClusterServersConfig clusterServersConfig = config.useClusterServers().addNodeAddress(clusterNodes.toArray(new String[clusterNodes.size()]));
        // 設置密碼
        clusterServersConfig.setPassword(redisConfigProperties.getPassword());
        RedissonClient redissonClient = Redisson.create(config);
        return redissonClient;
    }
}

 

4、測試調用

@RestController
@RequestMapping("")
public class RedisLockController {
    private static String product1Count = "product1Count";//商品1的數量key
    private static String lockKey = "testLockKey";//分布式鎖的key
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private Redisson redisson;

    /**
     * 初始化設置商品數量
     *
     * @return
     */
    @RequestMapping("/setProductCount")
    public String setValue() {
        redisTemplate.opsForValue().set(product1Count, "100");
        return "success";
    }

    /**
     * 模擬秒殺搶購,並發多個請求過來,查看是否出現超賣
     *
     * @return
     */
    @RequestMapping("/spike")
    public String spike() {
        String flag = "success";
        RLock lock = redisson.getLock(lockKey);
        try {
            //lock.lockAsync(5 , TimeUnit.SECONDS);
            //lock.lock(5, TimeUnit.SECONDS); //設置60秒自動釋放鎖  (默認是30秒自動過期)
            Future<Boolean> res = lock.tryLockAsync(100, 5, TimeUnit.SECONDS);
            boolean result = res.get();
            System.out.println("result:" + result);
            if (result) {
                int stock = Integer.parseInt(redisTemplate.opsForValue().get(product1Count).toString());
                if (stock > 0) {
                    redisTemplate.opsForValue().set(product1Count, (stock - 1) + "");
                } else {
                    flag = "fail";
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock(); //釋放鎖
        }
        return flag;
    }
}

 

 

其實Redisson還有其他好多的方法來解決現在互聯網中的好多問題,大家如果想了解更多的東西,可以去Redisson官網。

Redisson官網:

 參考:

https://www.cnblogs.com/milicool/p/9201271.html

https://www.cnblogs.com/zengnansheng/p/11426996.html

https://www.jianshu.com/p/3f3c3c733f32


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM