Redisson联锁
生活随笔
收集整理的這篇文章主要介紹了
Redisson联锁
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一、聯鎖概述
聯鎖(RedissonMultiLock)對象可以將多個RLock對象關聯為一個聯鎖,實現加鎖和解鎖功能。每個RLock對象實例可以來自于不同的Redisson實例。
如果負責儲存分布式鎖的某些Redis節點宕機以后,而且這些鎖正好處于鎖住狀態,就會出現死鎖問題。為了避免這種情況的發生,Redisson內部提供了一個監控鎖的看門狗??撮T狗的作用是在Redisson實例被關閉前,不斷延長鎖的有效期。默認情況下,看門狗的檢查鎖的超時時間是30秒,也可以通過修改Config.lockWatchdogTimeout來另行指定。
二、實踐
我是在Springboot項目中使用的Redisson分布式鎖。
2.1 pom.xml
<dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.14.1</version> </dependency>2.2 application.properties
server.port=8083## master 數據源配置 master.datasource.url=jdbc:mysql://10.5.146.156:3306/USDP?useUnicode=true&characterEncoding=utf8 master.datasource.username=root master.datasource.password=click1 master.datasource.driverClassName=com.mysql.jdbc.Driver# 連接池的配置信息 spring.datasource.type=com.alibaba.druid.pool.DruidDataSource # 初始化大小:建立物理連接的個數 spring.datasource.initialSize=5 # 最小連接數 spring.datasource.minIdle=5 # 最大連接數 spring.datasource.maxActive=20 # 配置獲取連接等待超時的時間 spring.datasource.maxWait=60000 # 配置間隔多久才進行一次檢測,檢測需要關閉的空閑連接,單位是毫秒 spring.datasource.timeBetweenEvictionRunsMillis=60000 # 配置一個連接在池中最小生存的時間,單位是毫秒 spring.datasource.minEvictableIdleTimeMillis=300000 # 用來檢測連接是否有效的sql,要求是一個查詢語句,常用select 'x'。如果validationQuery為null,testOnBorrow、testOnReturn、testWhileIdle都不會起作用 spring.datasource.validationQuery=SELECT 1 FROM DUAL spring.datasource.testWhileIdle=true spring.datasource.testOnBorrow=false spring.datasource.testOnReturn=false # 打開PSCache,并且指定每個連接上PSCache的大小; # 是否緩存preparedStatement,也就是PSCache。PSCache對支持游標的數據庫性能提升巨大,比如說oracle。在mysql下建議關閉 spring.datasource.poolPreparedStatements=false spring.datasource.maxPoolPreparedStatementPerConnectionSize=20 # 配置監控統計攔截的filters,去掉后監控界面sql無法統計,'wall'用于防火墻; # 屬性類型是字符串,通過別名的方式配置擴展插件,常用的插件有:監控統計用的filter:stat, 日志用的filter:log4j, 防御sql注入的filter:wall spring.datasource.filters=stat,wall,log4j # 通過connectProperties屬性來打開mergeSql功能;慢SQL記錄 spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000## 打印SQL語句 ##SpringBoot默認是使用info級別,沒有指定級別的就用Springboot默認規定的級別:root級別 logging.level.com.test=INFO #該屬性用來配置日志文件名,如果該屬性不配置,默認文件名為spring.log logging.file=/opt/applog/interfaceautotestagent/test.log #logging.file=/var/log/test.log logging.pattern.console=%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n #指定文件中日志的輸出格式 logging.pattern.file=%msg%n# REDIS # Redis數據庫索引(默認為0) spring.redis.database=0 ## Redis服務器地址 #spring.redis.host=10.237.78.40 ## Redis服務器連接端口 #spring.redis.port=6379 ## Redis服務器連接密碼(默認為空) #spring.redis.password= # 連接池最大連接數(使用負值表示沒有限制) spring.redis.lettuce.pool.max-active=16 # 連接池最大阻塞等待時間(使用負值表示沒有限制) spring.redis.lettuce.pool.max-wait=-1 # 連接池中的最大空閑連接 spring.redis.lettuce.pool.max-idle=8 # 連接池中的最小空閑連接 spring.redis.lettuce.pool.min-idle=0 # 連接超時時間(毫秒)spring boot 1.x,redisson新加的 spring.redis.timeout=60000 # 執行命令超時時間,單位毫秒 spring.redis.command-timeout: 15000 # 是否在從池中取出連接前進行檢驗,如果檢驗失敗,則從池中去除連接并嘗試取出另一個 spring.redis.test-on-borrow: true # 集群模式下,逗號分隔的鍵值對(主機:端口)形式的服務器列表 #spirng.redis.cluster.nodes=10.237.79.150:6379,10.237.79.150:6380,10.237.79.151:6379,10.237.79.151:6380,10.237.79.152:6379,10.237.79.152:6380 spirng.redis.cluster.nodes=172.24.83.165:6379,172.24.83.165:6380,172.24.83.165:6381,172.24.83.165:6382,172.24.83.165:6383,172.24.83.165:6384 # 集群模式下,集群最大轉發的數量 spring.redis.cluster.max-redirects=3 # 最大的連接重試次數 spring.redis.cluster.max-attempts=5#activemq spring.activemq.broker-url=tcp://10.237.78.6:61616 spring.activemq.user= spring.activemq.password= #spring.activemq.in-memory=true #spring.activemq.pool.enabled=false #使用發布/訂閱模式時,下邊配置需要設置成 true 是否使用默認的destination type來支持 publish/subscribe,默認: false spring.jms.pub-sub-domain=true ##指定最小的并發消費者數量 #spring.jms.listener.concurrency = 10 ##指定最大的并發消費者數量 #spring.jms.listener.max-concurrency = 102.3 RedisConfigProperties
package com.test.config;import lombok.Data; import org.redisson.config.Config; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.stereotype.Component;import java.util.List;@Data @Component @PropertySource("classpath:application.properties") public class RedisConfigProperties {@Value("${spirng.redis.cluster.nodes}")private String redisClusterNodes; }2.4 RedissonConfig
package com.test.config;import org.redisson.Redisson; import org.redisson.api.RedissonClient; import org.redisson.config.ClusterServersConfig; import org.redisson.config.Config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;import java.util.ArrayList; import java.util.List;@Configuration public class RedissonConfig {@Autowiredprivate RedisConfigProperties redisConfigProperties;@Beanpublic RedissonClient redissonClient1() {//redisson版本是3.5,集群的ip前面要加上“redis://”,不然會報錯,3.2版本可不加List<String> clusterNodes = new ArrayList<>();for (int i = 0; i < 2; i++) {clusterNodes.add("redis://" + redisConfigProperties.getRedisClusterNodes().split(",")[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;}@Beanpublic RedissonClient redissonClient2() {//redisson版本是3.5,集群的ip前面要加上“redis://”,不然會報錯,3.2版本可不加List<String> clusterNodes = new ArrayList<>();for (int i = 2; i < 4; i++) {clusterNodes.add("redis://" + redisConfigProperties.getRedisClusterNodes().split(",")[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;}@Beanpublic RedissonClient redissonClient3() {//redisson版本是3.5,集群的ip前面要加上“redis://”,不然會報錯,3.2版本可不加List<String> clusterNodes = new ArrayList<>();for (int i = 4; i < 5; i++) {clusterNodes.add("redis://" + redisConfigProperties.getRedisClusterNodes().split(",")[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;} }2.5 使用聯鎖
RLock lock1 = redissonClient1.getLock("lock1"); RLock lock2 = redissonClient2.getLock("lock2"); RLock lock3 = redissonClient3.getLock("lock3");RedissonMultiLock lock = new RedissonMultiLock(lock1, lock2, lock3); // 同時加鎖:lock1 lock2 lock3 // 所有的鎖都上鎖成功才算成功。 lock.lock(); ... lock.unlock();或
RedissonMultiLock lock = new RedissonMultiLock(lock1, lock2, lock3); // 給lock1,lock2,lock3加鎖,如果沒有手動解開的話,(leaseTime=10s)10秒鐘后將會自動解開 lock.lock(10, TimeUnit.SECONDS);// 為加鎖等待(waitTime=100s)100秒時間,并在加鎖成功10秒鐘后自動解開 boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS); ... lock.unlock();總結
以上是生活随笔為你收集整理的Redisson联锁的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 电路笔记(二)--稳压电路(一文读懂TL
- 下一篇: PlotNeuralNet绘制卷积神经网