分布式锁之RedissonLock

2024-05-07 02:20
文章标签 分布式 redissonlock

本文主要是介绍分布式锁之RedissonLock,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

什么是Redisson?
俗话说他就是看门狗,看门狗机制是一种用于保持Redis连接活跃性的方法,通常用于分布式锁的场景。看门狗的工作原理是:当客户端获取到锁之后,会对Redis中的一个特定的键设置一个有限的过期时间,然后每隔一段时间(默认是15秒),客户端会对这个键“续约”,即重新设置它的过期时间,以此来保持锁的持有状态,防止锁因为某些原因(如客户端崩溃或网络问题)而被释放。
在这里插入图片描述
以下是核心实战部分
配置文件读取

@ConfigurationProperties(prefix = "spring.redis.redisson"
)
@Data
public class RedissonProperties {/*** key前缀*/private String keyPrefix;/*** 拿锁等待时间(毫秒)*/private long waitTime = 10000;/*** 默认ttl时间(毫秒)*/private long leaseTime = 60000;@Value("${spring.redis.redisson.config.clusterServersConfig.nodeAddresses}")private String nodeAddresses;@Value("${spring.redis.redisson.config.clusterServersConfig.scanInterval}")private Integer scanInterval;@Value("${spring.redis.redisson.config.threads}")private Integer threads;@Value("${spring.redis.redisson.config.nettyThreads}")private Integer nettyThreads;@Value("${spring.redis.redisson.config.transportMode}")private String transportMode;
}

yml文件

spring:##redis集群配置redis:database: 0timeout: 5000msredisson:config:clusterServersConfig:nodeAddresses: redis://10.xxx.xx.x1:6379,redis://10.xxx.xx.x2:6379,redis://10.xxx.xx.x3:6379scanInterval: 1000nettyThreads: 0threads: 0transportMode: NIOkey-prefix: test:keylease-time: 80000wait-time: 50000

redisson自动配置类

@Configuration
@ConditionalOnClass({Redisson.class})
@EnableConfigurationProperties({RedissonProperties.class})
@Slf4j
public class RedissonAutoConfiguration {@Bean@ConditionalOnMissingBean({RedisConnectionFactory.class})public RedissonConnectionFactory redissonConnectionFactory(RedissonClient redisson) {return new RedissonConnectionFactory(redisson);}@Bean(destroyMethod = "shutdown")@ConditionalOnMissingBean({RedissonClient.class})public RedissonClient redisson(RedissonProperties redissonProperties) throws IOException {Config config = new Config();config.useClusterServers().addNodeAddress(redissonProperties.getNodeAddresses().split(",")).setScanInterval(redissonProperties.getScanInterval());config.setThreads(redissonProperties.getThreads()).setNettyThreads(redissonProperties.getNettyThreads()).setTransportMode(TransportMode.valueOf(redissonProperties.getTransportMode()));return Redisson.create(config);}@Bean@ConditionalOnMissingBean(name = {"redisTemplate"})public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {RedisTemplate<Object, Object> template = new RedisTemplate();template.setConnectionFactory(redisConnectionFactory);return template;}@Bean@ConditionalOnMissingBeanpublic StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {StringRedisTemplate template = new StringRedisTemplate();template.setConnectionFactory(redisConnectionFactory);return template;}}

redis的缓存类实现

@Service
public class RedisCache {@Autowiredprivate RedissonClient redisson;@Autowiredprivate RedissonProperties redissonProperties;/*** 缓存** @param key 缓存key* @param <T>* @return 缓存返回值*/public <T> T get(String key) {RBucket<T> bucket = redisson.getBucket(getKey(key));return bucket.get();}/*** 以string的方式读取缓存** @param key 缓存key* @return 缓存返回值*/public String getString(String key) {RBucket<String> bucket = redisson.getBucket(getKey(key), StringCodec.INSTANCE);return bucket.get();}/*** 以string的方式保存缓存(与其他应用共用redis时需要使用该函数)** @param key     缓存key* @param value   缓存值* @param expiredTime 缓存过期时间*/public void putString(String key, String value, long expiredTime) {RBucket<String> bucket = redisson.getBucket(getKey(key), StringCodec.INSTANCE);bucket.set(value, expiredTime, TimeUnit.MILLISECONDS);}/*** 如果不存在则写入缓存(string方式,不带有redisson的格式信息)** @param key     缓存key* @param value   缓存值* @param expiredTime 缓存过期时间*/public boolean putStringIfAbsent(String key, String value, long expiredTime) {RBucket<String> bucket = redisson.getBucket(getKey(key), StringCodec.INSTANCE);return bucket.trySet(value, expiredTime, TimeUnit.MILLISECONDS);}/*** 设置缓存** @param key     缓存key* @param value   缓存值* @param expiredTime 缓存过期时间* @param <T>     类型*/public <T> void put(String key, T value, long expiredTime) {RBucket<T> bucket = redisson.getBucket(getKey(key));bucket.set(value, expiredTime, TimeUnit.MILLISECONDS);}/*** 如果不存在则设置缓存** @param key     缓存key* @param value   缓存值* @param expiredTime 缓存过期时间* @param <T>     类型*/public <T> void putIfAbsent(String key, T value, long expiredTime) {RBucket<T> bucket = redisson.getBucket(getKey(key));bucket.trySet(value, expiredTime, TimeUnit.MILLISECONDS);}/*** 移除缓存** @param key*/public void remove(String key) {redisson.getBucket(getKey(key)).delete();}/*** 判断缓存是否存在** @param key* @return*/public boolean exists(String key) {return redisson.getBucket(getKey(key)).isExists();}private String getKey(String key) {return StringUtils.format("{0}:{1}", redissonProperties.getKeyPrefix(), key);}

获取和释放分布式锁接口
DistributedLock

/*** get分布式锁* @param lockKey* @param requestId* @param expireTime* @return*/public boolean getDistributedLock(String lockKey, String requestId, long expireTime);/*** remove分布式锁* @param lockKey* @param requestId* @return*/public boolean removeDistributedLock(String lockKey, String requestId);

实现DistributedLock的实现类逻辑

@Service
public class RedisDistributedLocker implements DistributedLocker {private static final Logger logger = LoggerFactory.getLogger(RedisDistributedLocker.class);@Autowiredprivate RedissonClient redisson;@Autowiredprivate RedissonProperties redissonProperties;public boolean getDistributedLock(String lockKey, String flagId, long expireTime) {boolean success;try {if (expireTime == 0) {expireTime = redissonProperties.getLeaseTime();}lockKey = StringUtils.format("{0}:{1}", redissonProperties.getKeyPrefix(), lockKey);RLock locker = redisson.getLock(lockKey);success = locker.tryLock(redissonProperties.getWaitTime(), expireTime, TimeUnit.MILLISECONDS);} catch (Exception e) {success = false;logger.error(StringUtils.format("获取分布式锁失败,lockKey={0}, flagId={1}, expirTime={2}", lockKey, flagId, expireTime), e);}return success;}public boolean releaseDistributedLock(String lockKey, String flagId) {boolean success = false;try {lockKey = StringUtils.format("{0}:{1}", redissonProperties.getKeyPrefix(), lockKey);RLock locker = redisson.getLock(lockKey);if (locker.isHeldByCurrentThread()) {locker.unlock();success = true;}} catch (Exception e) {success = false;logger.error(StringUtils.format("分布式锁失败,lockKey={0}, flagId={1}", lockKey, flagId), e);}return success;}

在需要的业务场景下使用 以下为伪代码

try {boolean ock = distributedLocker.getDistributedLock(lockKey, flagId, 9000L);if (!ock) {return;}// 实现自己的业务逻辑。。。。。。。。。。。。。。。。。。。。。。。。。} catch (Exception e) {e.printStackTrace();throw new RuntimeException(e.getMessage());} finally {distributedLocker.releaseDistributedLock(lockKey, flagId);}

以上的是分布式锁之RedissonLock 若需完整代码 可识别二维码后 给您发代码。
在这里插入图片描述

这篇关于分布式锁之RedissonLock的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/966063

相关文章

深入理解Apache Kafka(分布式流处理平台)

《深入理解ApacheKafka(分布式流处理平台)》ApacheKafka作为现代分布式系统中的核心中间件,为构建高吞吐量、低延迟的数据管道提供了强大支持,本文将深入探讨Kafka的核心概念、架构... 目录引言一、Apache Kafka概述1.1 什么是Kafka?1.2 Kafka的核心概念二、Ka

Python FastAPI+Celery+RabbitMQ实现分布式图片水印处理系统

《PythonFastAPI+Celery+RabbitMQ实现分布式图片水印处理系统》这篇文章主要为大家详细介绍了PythonFastAPI如何结合Celery以及RabbitMQ实现简单的分布式... 实现思路FastAPI 服务器Celery 任务队列RabbitMQ 作为消息代理定时任务处理完整

redis+lua实现分布式限流的示例

《redis+lua实现分布式限流的示例》本文主要介绍了redis+lua实现分布式限流的示例,可以实现复杂的限流逻辑,如滑动窗口限流,并且避免了多步操作导致的并发问题,具有一定的参考价值,感兴趣的可... 目录为什么使用Redis+Lua实现分布式限流使用ZSET也可以实现限流,为什么选择lua的方式实现

Seata之分布式事务问题及解决方案

《Seata之分布式事务问题及解决方案》:本文主要介绍Seata之分布式事务问题及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Seata–分布式事务解决方案简介同类产品对比环境搭建1.微服务2.SQL3.seata-server4.微服务配置事务模式1

java如何分布式锁实现和选型

《java如何分布式锁实现和选型》文章介绍了分布式锁的重要性以及在分布式系统中常见的问题和需求,它详细阐述了如何使用分布式锁来确保数据的一致性和系统的高可用性,文章还提供了基于数据库、Redis和Zo... 目录引言:分布式锁的重要性与分布式系统中的常见问题和需求分布式锁的重要性分布式系统中常见的问题和需求

Golang使用etcd构建分布式锁的示例分享

《Golang使用etcd构建分布式锁的示例分享》在本教程中,我们将学习如何使用Go和etcd构建分布式锁系统,分布式锁系统对于管理对分布式系统中共享资源的并发访问至关重要,它有助于维护一致性,防止竞... 目录引言环境准备新建Go项目实现加锁和解锁功能测试分布式锁重构实现失败重试总结引言我们将使用Go作

Redis分布式锁使用及说明

《Redis分布式锁使用及说明》本文总结了Redis和Zookeeper在高可用性和高一致性场景下的应用,并详细介绍了Redis的分布式锁实现方式,包括使用Lua脚本和续期机制,最后,提到了RedLo... 目录Redis分布式锁加锁方式怎么会解错锁?举个小案例吧解锁方式续期总结Redis分布式锁如果追求

集中式版本控制与分布式版本控制——Git 学习笔记01

什么是版本控制 如果你用 Microsoft Word 写过东西,那你八成会有这样的经历: 想删除一段文字,又怕将来这段文字有用,怎么办呢?有一个办法,先把当前文件“另存为”一个文件,然后继续改,改到某个程度,再“另存为”一个文件。就这样改着、存着……最后你的 Word 文档变成了这样: 过了几天,你想找回被删除的文字,但是已经记不清保存在哪个文件了,只能挨个去找。真麻烦,眼睛都花了。看

开源分布式数据库中间件

转自:https://www.csdn.net/article/2015-07-16/2825228 MyCat:开源分布式数据库中间件 为什么需要MyCat? 虽然云计算时代,传统数据库存在着先天性的弊端,但是NoSQL数据库又无法将其替代。如果传统数据易于扩展,可切分,就可以避免单机(单库)的性能缺陷。 MyCat的目标就是:低成本地将现有的单机数据库和应用平滑迁移到“云”端

laravel框架实现redis分布式集群原理

在app/config/database.php中配置如下: 'redis' => array('cluster' => true,'default' => array('host' => '172.21.107.247','port' => 6379,),'redis1' => array('host' => '172.21.107.248','port' => 6379,),) 其中cl