在微服务中很多情况下需要使用到分布式锁功能,而目前比较常见的方案是通过Redis来实现分布式锁,网上关于分布式锁的实现方式有很多,早期主要是基于Redisson等客户端,但在Spring Boot2.x以上版本中使用Redis时,其客户端库已经默认使用lettuce。
所以本文将直接介绍在Spring Boot2.x以上项目中快速使用Redis分布式锁的功能的方法,希望能够更新你的知识库!

Redis分布式锁原理概述

实际上Redis服务本身并不提供分布式锁这样的机制,但是作为全局Key-Value存储系统,客户端可以利用Redis提供的基本功能并通过一定的算法设计来实现分布式锁功能。目前已有不少博客文章及代码库描述了如何使用Redis来实现分布式锁,但是许多实现相对比较简单,安全性也比较低。在Redis的官方文档中推荐了一种叫做RedLock的算法来实现基于Redis的分布式锁功能,现阶段已存在基于该算法的多种语言版本的Redis客户端实现库。其中Java领域最为知名的是Redisson库。但由于Redisson不仅实现了分布式锁功能,还额外实现了一套Redis分布式数据结构,因此会显得比较重,加上最新的基于Spring Boot.2.x以上版本使用Redis时,其客户端库已经默认使用了lettuce(比Redisson、Jedis线程更安全、更轻量级的一种Java Redis客户端库)的封装,所以为了更加符合微服务场景下的使用,在实践中往往会选择基于RedLock算法自行实现分布式锁。

本案例也将演示如何RedLock算法来实现Redis分布式锁功能,不过在此之前让我们先来看看RedLock算法是如何运行的,示意图如下:

以上就是实现Redis分布式锁官方推荐的RedLock算法逻辑,它是一种多节点Redis的分布式锁算法,可以有效防止单节点故障问题。其执行步骤说明如下:

  • 首先Redis客户端获取当前系统时间,以毫秒为单位;
  • 然后客户端会顺序地尝试向Redis集群中的每个节点获取锁,其具体步骤是使用相同的键Key名和随机值;在向每个Redis节点获取锁的过程中,客户端会以比锁过期时间小得多的时间来设定超时机制,例如锁的整个超时时间为10秒,集群有5个节点,那么每个节点获取锁的超时时间可能会被限制在5~50毫秒之间,这是为了防止在某个节点不可用的情况下,客户端等待时间过长,造成性能阻塞;
  • 之后随着各节点获取锁结果的反馈,Redis客户端会对获取情况进行判断,如果获取各节点锁的总时间小于锁的超时时间设置,并且成功获取锁的节点数目大于N/2+1个(例如5个节点至少要有3个节点成功获取锁),满足上述条件的情况下,Redis客户端才会认为获取锁成功,否则就会认为锁获取失败,并依次释放掉各个节点的锁信息;
  • 获取锁成功后即可以安全地执行操作,完成后再依次释放各节点锁持有的锁信息;

实现上述算法的Redis客户端可以基本上保证分布式锁的有效性及安全性的几个基本特性要求:

  • 互斥:任何时刻只能有一个Redis客户端获取锁;
  • 无死锁:即使锁定资源的服务崩溃或者分区,仍然能释放锁);
  • 容错性:只要多数redis节点(一半以上)在使用,Redis客户端就可以获取和释放锁;

Spring Boot集成使用方式

通过前面内容的描述,相信你对实现Redis分布式锁的基本算法应该有了一定的认识和理解。而在实践的过程中可以依据该算法自行定制实现,但实际上Spring早就提供了基于该算法的Redis的分布式锁的实现。其具体使用步骤如下:

1)在工程pom.xml文件中引入Spring Integration依赖,代码如下:

<!-- spring integration -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-integration</artifactId>
</dependency>
<!-- spring integration与redis结合,实现redis分布式锁 -->
<dependency><groupId>org.springframework.integration</groupId><artifactId>spring-integration-redis</artifactId>
</dependency>

目前Spring所提供的分布式锁相关的代码被迁移在Spring Integration子项目中,所以这里引入其相关依赖。

2)编写RedisLock的配置类,代码如下:

@Configuration
public class RedisLockConfiguration {@Beanpublic RedisLockRegistry redisLockRegistry(RedisConnectionFactory redisConnectionFactory) {return new RedisLockRegistry(redisConnectionFactory, "payment");}
}

以上配置代码加载的前提在于应用已经集成了Redis服务访问链接信息,具体Spring Boot项目集成Redis访问的方式比较简单可以参考其他资料。

3)分布式锁的具体使用方式,代码片段如下:

/*** 引入Redis分布式锁依赖组件*/
@Autowired
private RedisLockRegistry redisLockRegistry;@Override
public UnifiedPayBO unifiedPay(UnifiedPayDTO unifiedPayDTO) {...//创建Redis分布式锁Lock lock = redisLockRegistry.obtain(redisLockPrefix + unifiedPayDTO.getOrderId());try {      //尝试获取锁boolean isLock = lock.tryLock(1, TimeUnit.SECONDS);if (isLock) {//执行业务逻辑...}} catch (InterruptedException e) {e.printStackTrace();} finally {//释放分布式锁lock.unlock();}...
}

上述代码为订单防重时使用Redis分布锁的示例代码,通过依赖注入RedisLockRegistry实例来实现分布式锁的相关操作,例如obtain()方法创建锁、tryLock()持有锁及unlock()释放锁等。

写在最后:

欢迎大家关注我新开通的公众号【风平浪静如码】,海量Java相关文章,学习资料都会在里面更新,整理的资料也会放在里面。

觉得写的还不错的就点个赞,加个关注呗!点关注,不迷路,持续更新!!!

redis分布式锁 在集群模式下如何实现_收藏慢慢看系列:简洁实用的Redis分布式锁用法...相关推荐

  1. 关于Redis集群模式下,使用mget通过keys批量获取value时的解决方案

    关于Redis集群模式下,使用mget通过keys批量获取value时的解决方案 今天在做项目的时候,需要使用到mget命令,通过一个批量的key去获取对应的value集合,但是取值的时候,报了这个错 ...

  2. strom-1.1.0模拟单词统计功能,Spout编写,Bolt编写,TopologyDriver编写,本地模式运行,集群模式运行,集群模式下看输出结果

    统计文本中的单词出现的频率,其中文本内容如下: 创建项目 项目结构如下: 创建pom.xml,代码如下: <?xml version="1.0" encoding=" ...

  3. RSF-Center,集群模式下-协调数据结构

    为什么80%的码农都做不了架构师?>>>    RSF是一个轻量化的分布式服务框架.支持点对点调用,也支持分布式调用.典型的应用场景是,将同一个服务部署在多个Server上提供 re ...

  4. 如何访问集群中指定的服务器,【Nacos源码之配置管理 六】集群模式下服务器之间是如何互相感知的...

    前言 我们用Nacos当配置中心的时候,上一篇文章中 [Nacos源码之配置管理 五]为什么把配置文件Dump到磁盘中 知道了,所有的配置文件都会Dump到服务器的本地磁盘中, 那么集群模式下: 服务 ...

  5. zookeeper专题:zookeeper集群模式下,leader选举流程分析

    文章目录 Zookeeper 集群模式一共有三种类型的角色 1. zookeeper启动时leader选举流程 1.1 加载配置文件,设置基本信息 1.2 指定快速选举算法,启动多级队列.线程 1.3 ...

  6. redis的三种集群模式原理

    一.主从同步/复制 通过持久化功能,Redis保证了即使在服务器重启的情况下也不会丢失(或少量丢失)数据,因为持久化会把内存中数据保存到硬盘上,重启会从硬盘上加载数据. 但是由于数据是存储在一台服务器 ...

  7. quartz集群模式下qrtz_triggers表trigger_state变ERROR分析

    最近在正式环境新增了一个定时任务,项目启动后,新增的任务总是跑一两次就不跑了,排查发现trigger_state变为ERROR了. 一.Quartz重要表含义 1)qrtz_calendars:以Bl ...

  8. 集群模式下,redis锁的问题,红锁

    在使用redis来实现分布式锁的时候,如果redis是集群的,比如1主4从,这种主从模式就会存在延迟问题,导致加锁出现问题. 此时就应该使用红锁的方案,即在代码中不依赖于主从,将这5台机器视为平等的, ...

  9. Hadoop框架:集群模式下分布式环境搭建

    本文源码:GitHub·点这里 || GitEE·点这里 一.基础环境配置 1.三台服务 准备三台Centos7服务,基础环境从伪分布式环境克隆过来. 133 hop01,134 hop02,136 ...

最新文章

  1. C++知识点19——使用C++标准库(再谈string——string的初始化、赋值、添加、删除、访问)
  2. js中的attribute详解
  3. 10分钟理解CSS3 FlexBox
  4. 【翻译】Ext JS最新技巧——2015-8-11
  5. From 百度知道 SQLSERVER 字符集排序规则简单说明
  6. 利用shell脚本添加环境变量
  7. 詹金斯搭建_詹金斯的Maven报告
  8. 【CCF】 201604-1折点计数
  9. 云设置下如何满足客户的数据安全需求?
  10. java stream, LIST ,ArrayList常用操作
  11. “舱驾融合”技术发展趋势分析
  12. AssertionError: Incompatible version of pycocotools is installed.
  13. 【论文翻译】Deep Learning
  14. win10计算机共享在哪,快速共享电脑文件,win10的“就近共享”功能了解一下!...
  15. 计算机启动很慢,win7开机慢解决方法
  16. java数据类型 枚举_枚举(enum)属于原始数据类型(primitive typ
  17. 基于you-get的视频批量下载
  18. 今日头条用户搜索“室内设计”显示的自媒体粉丝数量及分布情况统计(2020.1.8)
  19. UDP - Nginx配置端口保持时间proxy_timeout
  20. C++与QML混合编程

热门文章

  1. 笔记本通过网线连接并控制工控机
  2. 【AJAX】Ajax学习总结
  3. 深度学习网络模型可视化netron
  4. LeetCode简单题之反转单词前缀
  5. AI人工智能天机芯芯片
  6. 用Microsoft DirectX光线跟踪改善渲染质量
  7. 2021年大数据Spark(四十二):SparkStreaming的Kafka快速回顾与整合说明
  8. Java IDEA Debug进制二维数组
  9. Unable to inject views for 包名.activity
  10. [洛谷1383]高级打字机 题解