基于Redis的分布式共享锁
发布日期:2021-11-15 14:57:36
浏览次数:25
分类:技术文章
本文共 3844 字,大约阅读时间需要 12 分钟。
此文档主要演示了如何使用 Spring Boot 集成RedisTemplate实现分布式锁。
application.yml
spring: redis: host: localhost # 连接超时时间(记得添加单位,Duration) timeout: 10000ms # Redis默认情况下有16个分片,这里配置具体使用的分片 # database: 0 lettuce: pool: # 连接池最大连接数(使用负值表示没有限制) 默认 8 max-active: 8 # 连接池最大阻塞等待时间(使用负值表示没有限制) 默认 -1 max-wait: -1ms # 连接池中的最大空闲连接 默认 8 max-idle: 8 # 连接池中的最小空闲连接 默认 0 min-idle: 0
pom.xml
基于 Spring Boot 引入redis
org.springframework.boot spring-boot-starter-data-redis org.apache.commons commons-pool2
RedisConfig
基于Spring Boot 的 redis配置
/** * redis配置 * @author xiehengxing * @date 2020/7/29 18:30 */@Configuration@AutoConfigureAfter(RedisAutoConfiguration.class)@EnableCachingpublic class RedisConfig { /** * 默认情况下的模板只能支持RedisTemplate,也就是只能存入字符串,因此支持序列化 */ @Bean public RedisTemplate redisCacheTemplate(LettuceConnectionFactory redisConnectionFactory) { RedisTemplate template = new RedisTemplate<>(); template.setKeySerializer(new StringRedisSerializer()); template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); template.setConnectionFactory(redisConnectionFactory); return template; } /** * 配置使用注解的时候缓存配置,默认是序列化反序列化的形式,加上此配置则为 json 形式 */ @Bean public CacheManager cacheManager(RedisConnectionFactory factory) { // 配置序列化 RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig(); RedisCacheConfiguration redisCacheConfiguration = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())).serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer())); return RedisCacheManager.builder(factory).cacheDefaults(redisCacheConfiguration).build(); }}
RedisLock
分布式共享锁的实现
/** * 分布式共享锁 * @author xiehengxing * @date 2020/8/2 10:40 */@Slf4j@Componentpublic class RedisLock { @Autowired private RedisTemplate redisTemplate; /** * 共享锁默认时长(秒) */ private static final long TIMEOUT = 60; /** * 超时时长(秒) */ private static final long OVERTIME = 6; /** * 获取锁 * @param key * @param requestId * @return */ public boolean lock(String key, String requestId){ long startTime = System.currentTimeMillis(); for(;;) { boolean locked = redisTemplate.opsForValue().setIfAbsent(key, requestId, TIMEOUT, TimeUnit.SECONDS); if (locked) { return true; } if ((System.currentTimeMillis() - startTime)/1000 > OVERTIME) { return false; } try { Thread.sleep(300); } catch (InterruptedException e) { log.error("线程被中断" + Thread.currentThread().getId(), e); } } } /** * 使用lua脚本解锁 * @param key * @param requestId * @return */ public boolean unlock(String key, String requestId) { if (StringUtils.isEmpty(key) || StringUtils.isEmpty(requestId)){ return false; } DefaultRedisScriptredisScript = new DefaultRedisScript(); //用于解锁的lua脚本位置 redisScript.setScriptText( "if redis.call('get', KEYS[1]) == ARGV[1] then " + "return redis.call('del', KEYS[1]) " + "else " + "return 0" + "end"); redisScript.setResultType(Long.class); //没有指定序列化方式,默认使用上面配置的 Object result = redisTemplate.execute(redisScript, Collections.singletonList(key), requestId); return result.equals(Long.valueOf(1)); }}
转载地址:https://blog.csdn.net/qq_39739458/article/details/107974476 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
表示我来过!
[***.240.166.169]2024年04月25日 20时40分37秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
学不下去了怎么办?
2019-04-27
二叉树的前中后序遍历(迭代法)(带动画)
2019-04-27
【小技巧】【XShell】【Xftp】Windows桌面与Linux虚拟机互传文件
2019-04-27
【redis入门】Centos下安装redis
2019-04-27
【redis入门】redis安装后相关知识串讲
2019-04-27
【redis】来吧,展示一下redis 发布-订阅模式
2019-04-27
当下热点词再学:redis缓存预热、更新、降级,限流
2019-04-27
【redis6.0.6】redis源码慢慢学,慢慢看 -- 第五天:adlist
2021-06-30
别抖,OK? 操作系统抖动现象、网络抖动与延迟、函数抖动之防抖与节流,串讲
2021-06-30
通过域名获取主机IP -- struct addrinfo
2021-06-30
【C++】算法集锦(8):从两数和问题拓展到一百数和问题
2021-06-30
【C++】算法集锦(9):背包问题
2021-06-30
【C++】算法集锦(10)通俗讲kmp算法
2021-06-30
【C++】算法集锦(12):高楼扔鸡蛋
2021-06-30
【图解】拥塞控制
2021-06-30
线程上下文切换
2021-06-30
什么是服务熔断?
2021-06-30