日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

SpringBoot集成Redission实现分布式缓存

發布時間:2025/3/20 javascript 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SpringBoot集成Redission实现分布式缓存 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

github地址:https://github.com/redisson/redisson

一.源碼分析

trylock

tryAcquire

針對過期時間做不同的轉發處理

tryLockInnerAsync

? ?<T> RFuture<T> tryLockInnerAsync(long leaseTime, TimeUnit unit, long threadId, RedisStrictCommand<T> command) {this.internalLockLeaseTime = unit.toMillis(leaseTime);return this.commandExecutor.evalWriteAsync(this.getName(), LongCodec.INSTANCE, command, "if (redis.call('exists', KEYS[1]) == 0) then redis.call('hset', KEYS[1], ARGV[2], 1); redis.call('pexpire', KEYS[1], ARGV[1]); return nil; end; if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then redis.call('hincrby', KEYS[1], ARGV[2], 1); redis.call('pexpire', KEYS[1], ARGV[1]); return nil; end; return redis.call('pttl', KEYS[1]);", Collections.singletonList(this.getName()), new Object[]{this.internalLockLeaseTime, this.getLockName(threadId)});}

通過lua腳本來實現加鎖的操作

  • 判斷lock鍵是否存在,不存在直接調用hset存儲當前線程信息并且設置過期時間,返回nil,告訴客戶端直接獲取到鎖。

  • 判斷lock鍵是否存在,存在則將重入次數加1,并重新設置過期時間,返回nil,告訴客戶端直接獲取到鎖。

  • 被其它線程已經鎖定,返回鎖有效期的剩余時間,告訴客戶端需要等待。

  • unlock

    ? ?protected RFuture<Boolean> unlockInnerAsync(long threadId) {return this.commandExecutor.evalWriteAsync(this.getName(), LongCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN, "if (redis.call('hexists', KEYS[1], ARGV[3]) == 0) then return nil;end; local counter = redis.call('hincrby', KEYS[1], ARGV[3], -1); if (counter > 0) then redis.call('pexpire', KEYS[1], ARGV[2]); return 0; else redis.call('del', KEYS[1]); redis.call('publish', KEYS[2], ARGV[1]); return 1; end; return nil;", Arrays.asList(this.getName(), this.getChannelName()), new Object[]{LockPubSub.UNLOCK_MESSAGE, this.internalLockLeaseTime, this.getLockName(threadId)});}
  • 如果lock鍵不存在,發消息說鎖已經可用,發送一個消息

  • 如果鎖不是被當前線程鎖定,則返回nil

  • 由于支持可重入,在解鎖時將重入次數需要減1

  • 如果計算后的重入次數>0,則重新設置過期時間

  • 如果計算后的重入次數<=0,則發消息說鎖已經可用

  • 二.在SpringBoot中的使用

    1.pom依賴

    <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.8.1</version></dependency><dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.11.5</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>

    2.Lock接口

    public interface DistributedLocker {RLock lock(String lockKey); ?RLock lock(String lockKey, int timeout); ?RLock lock(String lockKey, TimeUnit unit, int timeout); ?boolean tryLock(String lockKey, TimeUnit unit, int waitTime, int leaseTime); ?void unlock(String lockKey); ?void unlock(RLock lock); }

    3.Lock接口實現類

    public class RedissonDistributedLocker implements DistributedLocker { ?private RedissonClient redissonClient; ? ?public void setRedissonClient(RedissonClient redissonClient) {this.redissonClient = redissonClient;} ?@Overridepublic RLock lock(String lockKey) {RLock lock = redissonClient.getLock(lockKey);lock.lock();return lock;} ?@Overridepublic RLock lock(String lockKey, int leaseTime) {RLock lock = redissonClient.getLock(lockKey);lock.lock(leaseTime, TimeUnit.SECONDS);return lock;} ?@Overridepublic RLock lock(String lockKey, TimeUnit unit, int timeout) {RLock lock = redissonClient.getLock(lockKey);lock.lock(timeout, unit);return lock;} ?@Overridepublic boolean tryLock(String lockKey, TimeUnit unit, int waitTime, int leaseTime) {RLock lock = redissonClient.getLock(lockKey);try {return lock.tryLock(waitTime, leaseTime, unit);} catch (InterruptedException e) {return false;}} ?@Overridepublic void unlock(String lockKey) {RLock lock = redissonClient.getLock(lockKey);lock.unlock();} ?@Overridepublic void unlock(RLock lock) {lock.unlock();} }

    4.RedissLock工具類

    public class RedissLockUtil {private static DistributedLocker redissLock; ?public static void setLocker(DistributedLocker locker) {redissLock = locker;} ?/*** 加鎖* @param lockKey* @return*/public static RLock lock(String lockKey) {return redissLock.lock(lockKey);} ?/*** 釋放鎖* @param lockKey*/public static void unlock(String lockKey) {redissLock.unlock(lockKey);} ?/*** 釋放鎖* @param lock*/public static void unlock(RLock lock) {redissLock.unlock(lock);} ?/*** 帶超時的鎖* @param lockKey* @param timeout 超時時間 ? 單位:秒*/public static RLock lock(String lockKey, int timeout) {return redissLock.lock(lockKey, timeout);} ?/*** 帶超時的鎖* @param lockKey* @param unit 時間單位* @param timeout 超時時間*/public static RLock lock(String lockKey, TimeUnit unit , int timeout) {return redissLock.lock(lockKey, unit, timeout);} ?/*** 嘗試獲取鎖* @param lockKey* @param waitTime 最多等待時間* @param leaseTime 上鎖后自動釋放鎖時間* @return*/public static boolean tryLock(String lockKey, int waitTime, int leaseTime) {return redissLock.tryLock(lockKey, TimeUnit.SECONDS, waitTime, leaseTime);} ?/*** 嘗試獲取鎖* @param lockKey* @param unit 時間單位* @param waitTime 最多等待時間* @param leaseTime 上鎖后自動釋放鎖時間* @return*/public static boolean tryLock(String lockKey, TimeUnit unit, int waitTime, int leaseTime) {return redissLock.tryLock(lockKey, unit, waitTime, leaseTime);} }

    5.屬性裝配類

    @Configuration @ConfigurationProperties(prefix = "redisson") @ConditionalOnProperty("redisson.password") @Data public class RedissonProperties {private int timeout = 3000;private String address;private String password;private int database = 0;private int connectionPoolSize = 64;private int connectionMinimumIdleSize = 10;private int slaveConnectionPoolSize = 250;private int masterConnectionPoolSize = 250;private String[] sentinelAddresses;private String masterName; }

    6.SpringBoot自動裝配類

    @Configuration @ConditionalOnClass(Config.class) @EnableConfigurationProperties(RedissonProperties.class) public class RedissonAutoConfiguration { ?@Autowiredprivate RedissonProperties redissonProperties; ?/*** 哨兵模式自動裝配** @return*/ /* ? @Bean@ConditionalOnProperty(name = "redisson.master-name")RedissonClient redissonSentinel() {Config config = new Config();SentinelServersConfig serverConfig = config.useSentinelServers().addSentinelAddress(redissonProperties.getSentinelAddresses()).setMasterName(redissonProperties.getMasterName()).setTimeout(redissonProperties.getTimeout()).setMasterConnectionPoolSize(redissonProperties.getMasterConnectionPoolSize()).setSlaveConnectionPoolSize(redissonProperties.getSlaveConnectionPoolSize()); ?if (StringUtils.isNotBlank(redissonProperties.getPassword())) {serverConfig.setPassword(redissonProperties.getPassword());}return Redisson.create(config);}*/ ?/*** 單機模式自動裝配** @return*/@Bean@ConditionalOnProperty(name = "redisson.address")RedissonClient redissonSingle() {Config config = new Config();SingleServerConfig serverConfig = config.useSingleServer().setAddress(redissonProperties.getAddress()).setTimeout(redissonProperties.getTimeout()).setConnectionPoolSize(redissonProperties.getConnectionPoolSize()).setConnectionMinimumIdleSize(redissonProperties.getConnectionMinimumIdleSize()); ?if (StringUtils.isNotBlank(redissonProperties.getPassword())) {serverConfig.setPassword(redissonProperties.getPassword());} ?return Redisson.create(config);} ?/*** 裝配locker類,并將實例注入到RedissionLockUtil中** @return*/@BeanDistributedLocker distributedLocker(RedissonClient redissonClient) {RedissonDistributedLocker locker = new RedissonDistributedLocker();locker.setRedissonClient(redissonClient);RedissLockUtil.setLocker(locker);return locker;} }

    7.配置文件

    redisson:address: redis://localhost:6379password:#哨兵模式的配置#sentinel-addresses: xxx.xxx.xxx.xxx:port,xxx.xxx.xxx.xxx:port

    8.加鎖測試

    ? ?@GetMapping("/test")public String testRedission() {CountDownLatch countDownLatch = new CountDownLatch(10); ?for (int i = 0; i < 10; i++) {new Thread(() -> {try {countDownLatch.await();} catch (InterruptedException e) {e.printStackTrace();}RedissLockUtil.lock("test");for (int j = 0; j < 100; j++) {System.out.println(Thread.currentThread() + "---" + j);try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}} ?RedissLockUtil.unlock("test");}).start();countDownLatch.countDown();} ?return "success";}

    總結

    以上是生活随笔為你收集整理的SpringBoot集成Redission实现分布式缓存的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。