Redisson 分布式锁的使用详解
一、分布式锁的概述
1.1 分布式锁的背景
在单机系统中,Java 提供了 synchronized
和 Lock
等锁机制来确保并发情况下的线程安全。然而,在分布式系统中,多个服务实例运行在不同的物理或虚拟机上,无法直接使用这些本地的锁机制来控制对共享资源的访问。
为了在分布式环境中控制对共享资源的访问,就需要引入一种能够跨多台服务器实例的锁机制,这就是分布式锁。Redis 作为一种高性能的内存数据库,提供了基于 Redis 的分布式锁实现。Redisson 基于 Redis 对分布式锁进行了封装,提供了简洁易用的 API 来管理分布式锁。
1.2 分布式锁的特性
一个完整的分布式锁需要具备以下几个特性:
- 互斥性:同一时刻只能有一个客户端能获得锁,其他客户端必须等待锁被释放后才能继续操作。
- 容错性:如果持有锁的客户端因为网络或系统故障而没有主动释放锁,锁应当能够被安全地释放。
- 高可用性:锁的请求和释放过程应该是高效的,且在 Redis 节点出现故障时,系统依然能够正常工作。
二、Redisson 分布式锁的原理
Redisson 分布式锁基于 Redis 的 SETNX
(set if not exists) 命令实现。基本的原理如下:
- 加锁:客户端请求加锁时,会向 Redis 发送一个
SETNX
命令,如果返回值为 1,表示加锁成功。如果返回 0,则说明锁已经被其他客户端持有,当前客户端需要等待。 - 自动过期:为了防止客户端因故障而无法释放锁,锁的持有是有过期时间的。通过 Redis 的
EXPIRE
命令,锁在加锁时同时设置过期时间,到期后锁将自动释放。 - 解锁:锁持有者执行完任务后,主动向 Redis 发送命令删除锁的 key,从而释放锁,其他等待的客户端才能继续加锁。
Redisson 通过封装 Redis 的这些基础命令,提供了 RLock
接口来方便地实现分布式锁。
三、Redisson 分布式锁的使用
3.1 引入 Redisson 依赖
在项目中使用 Redisson,首先需要在 pom.xml
文件中引入 Redisson 的依赖:
<dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.16.3</version>
</dependency>
3.2 Redisson 配置
为了使用 Redisson 分布式锁,首先需要配置 Redisson 客户端。Redisson 支持单节点模式、主从模式、集群模式和哨兵模式等多种 Redis 部署模式。这里我们以单节点模式为例:
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;public class RedissonConfig {public RedissonClient redissonClient() {Config config = new Config();config.useSingleServer().setAddress("redis://127.0.0.1:6379");return Redisson.create(config);}
}
3.3 使用分布式锁
在配置好 Redisson 客户端后,可以通过 RedissonClient
来获取 RLock
对象,进行分布式加锁和解锁操作。下面是一个简单的使用示例:
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;public class DistributedLockExample {private final RedissonClient redissonClient;public DistributedLockExample(RedissonClient redissonClient) {this.redissonClient = redissonClient;}public void executeWithLock() {// 获取锁对象RLock lock = redissonClient.getLock("myLock");try {// 加锁lock.lock();System.out.println("获得锁,执行临界区代码");// 模拟业务逻辑Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();} finally {// 解锁lock.unlock();System.out.println("释放锁");}}
}
在上面的示例中,我们通过 redissonClient.getLock("myLock")
获取一个名为 myLock
的锁对象,并在执行完任务后通过 lock.unlock()
主动释放锁。
3.4 设置锁的超时时间
为了防止因异常情况导致锁无法释放,Redisson 提供了设置锁超时时间的功能。在获取锁时,可以通过 lock.lock(long leaseTime, TimeUnit unit)
方法指定锁的持有时间。例如,下面的代码将设置锁的持有时间为 10 秒:
public void executeWithTimeoutLock() {RLock lock = redissonClient.getLock("myLock");try {// 加锁并设置超时时间为10秒lock.lock(10, TimeUnit.SECONDS);System.out.println("获得锁,执行临界区代码");// 模拟业务逻辑Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();} finally {// 无需主动解锁,锁会在10秒后自动释放if (lock.isHeldByCurrentThread()) {lock.unlock();}System.out.println("释放锁");}
}
四、Redisson 分布式锁的应用场景
4.1 控制并发访问
在电商、抢购等高并发场景中,多个用户同时发起对同一商品的抢购请求,此时需要使用分布式锁来控制对库存资源的并发访问,防止超卖或重复购买。
public void purchase(String productId) {RLock lock = redissonClient.getLock("product:" + productId);try {// 尝试获取锁if (lock.tryLock(5, 10, TimeUnit.SECONDS)) {// 执行购买逻辑System.out.println("购买成功");} else {System.out.println("获取锁失败,购买失败");}} catch (InterruptedException e) {e.printStackTrace();} finally {if (lock.isHeldByCurrentThread()) {lock.unlock();}}
}
4.2 分布式任务调度
在分布式系统中,任务调度器往往有多个实例在同时运行。如果多个实例同时执行相同的任务,可能会导致数据重复处理或任务冲突。此时可以通过 Redisson 分布式锁确保同一时刻只有一个实例能够执行任务。
public void scheduleTask() {RLock lock = redissonClient.getLock("taskLock");try {if (lock.tryLock(1, TimeUnit.MINUTES)) {System.out.println("获得锁,执行调度任务");// 执行定时任务}} catch (InterruptedException e) {e.printStackTrace();} finally {if (lock.isHeldByCurrentThread()) {lock.unlock();}}
}
4.3 分布式事务
在分布式系统中,为了确保多个数据库或服务之间的数据一致性,可以使用 Redisson 分布式锁来控制对共享资源的访问,从而实现分布式事务的控制。
五、Redisson 分布式锁的优缺点
5.1 优点
- 实现简单:Redisson 提供了简洁的 API,开发者可以轻松地实现分布式锁功能。
- 丰富的分布式工具:除了分布式锁,Redisson 还提供了其他分布式工具,如分布式集合、队列、布隆过滤器等,适用于多种场景。
- 自动续期:Redisson 提供了自动续期功能,防止因任务执行时间过长导致锁意外释放。
5.2 缺点
- 依赖 Redis:Redisson 是基于 Redis 实现的分布式锁,依赖于 Redis 的可用性和性能。
- **锁的粒度
问题**:在使用分布式锁时,需要合理设计锁的粒度。锁粒度过大会导致性能瓶颈,锁粒度过小则可能导致竞争加剧。
六、总结
Redisson 作为 Redis 的高级客户端,提供了简单易用的分布式锁实现,能够很好地解决分布式系统中的并发控制问题。通过 Redisson,开发者可以快速实现分布式锁,并应用到电商、任务调度、分布式事务等场景中。
在使用 Redisson 分布式锁时,除了基本的加锁和解锁操作外,还需要合理设计锁的粒度,确保锁的可用性和系统性能的平衡。
相关文章:
Redisson 分布式锁的使用详解
一、分布式锁的概述 1.1 分布式锁的背景 在单机系统中,Java 提供了 synchronized 和 Lock 等锁机制来确保并发情况下的线程安全。然而,在分布式系统中,多个服务实例运行在不同的物理或虚拟机上,无法直接使用这些本地的锁机制来控…...

计算机网络:物理层 --- 基本概念、编码与调制
目录 一. 物理层的基本概念 二. 数据通信系统的模型 三. 编码 3.1 基本概念 3.2 不归零制编码 3.3 归零制编码 3.4 曼切斯特编码 3.5 差分曼切斯特编码 编辑 四. 调制 4.1 调幅 4.2 调频 4.3 调相 4.4 混合调制 今天我们讲的是物理…...

使用Maven创建一个Java项目并在repository中使用
JDK环境:1.8.0_371 Maven环境 :Apache Maven 3.6.3 配置完成jdk和mvn后,进入到指定文件夹下执行如下语句: mvn archetype:generate -DgroupIdtop.chengrongyu -DartifactIdCyberSpace -DarchetypeArtifactIdmaven-archetype-quic…...

如何使用IIC外设(硬件IIC)
本文重点叙述如何使用芯片自带的 IIC 外设,即硬件 IIC,实现 IIC 通信。文章《IIC通信基础_cpu的iic通信-CSDN博客》 中,叙述了软件 IIC 通信和硬件 IIC 通信的区别, 并且重点叙述了 IIC 的通信协议。在使用软件进行 IIC 通信时&am…...

使用 Vue 3、Vite 和 TypeScript 的环境变量配置
使用 Vue 3、Vite 和 TypeScript 的环境变量配置 在开发现代前端应用时,环境变量是一个非常重要的概念。它可以帮助我们根据不同的环境(开发、测试、生产)配置不同的行为,比如 API 请求地址、调试选项等。在 Vue 3、Vite 和 Type…...

F28335 的串行外设接口(以下简称 SPI)
1 SPI 介绍 1.1 SPI 简介 1.2 F28335 的 SPI模块介绍 (1)F28335 的 SPI 特点...

科技引领未来生活——“光影漫游者”展览馆应用—轻空间
随着科技的快速发展,展览馆作为展示文化、科技和艺术的场所,正逐渐从传统的静态展示向高科技互动体验转变。由轻空间打造的“光影漫游者”展览馆,凭借其前沿的气承式结构和智能化系统,将参观者带入了一个未来感十足、充满科技魅力…...
ego-planner开源代码之启动参数介绍分析
ego-planner开源代码之启动参数介绍&分析 1. 源由2. 逻辑分析3. 启动参数section 1 三维地图尺寸section 2 里程计话题映射section 3 advanced_param.xml配置section 3.1section 3.2section 3.3section 3.4section 3.5section 3.6section 3.7section 3.8 section 4 轨迹服务…...
828 华为云征文|华为 Flexus 云服务器打造 Laverna 在线笔记应用
一、引言 在当今数字化时代,高效的笔记管理工具对于学习、工作和生活都至关重要。Laverna 作为一款功能强大的开源在线笔记应用,提供了 Markdown 编辑、加密支持等特性,是替代 Evernote 的绝佳选择。在 2024 年 9 月 14 日这个充满创新的日子…...
数据结构与算法-Trie树添加与搜索
trie树的使用场景 我们若需要制作一个通讯录的软件,使用常规树结构查询的复杂度为O(logn),但trie树的复杂度确与数据多少无关,与单词长度有关,这就大大缩减的查询的时间复杂度。 trie树的基本实现 基础结构 package com.study.trieDemo;i…...

AIGC专栏15——CogVideoX-Fun详解 支持图文生视频 拓展CogVideoX到256~1024任意分辨率生成
AIGC专栏15——CogVideoX-Fun详解 支持图&文生视频 拓展CogVideoX到256~1024任意分辨率生成 学习前言项目特点生成效果相关地址汇总源码下载地址 CogVideoX-Fun详解技术储备Diffusion Transformer (DiT)Stable Diffusion 3EasyAnimate-I2V 算法细节算法组成InPa…...

BFS 解决多源最短路问题
文章目录 多源BFS542. 01 矩阵题目解析算法原理代码实现 1020. 飞地的数量题目解析算法原理 1765. 地图中的最高点题目解析算法原理代码实现 1162. 地图分析题目解析算法原理代码实现 多源BFS 单源最短路: 一个起点、一个终点 多源最短路: 可以多个起点…...

论文笔记:交替单模态适应的多模态表征学习
整理了CVPR2024 Multimodal Representation Learning by Alternating Unimodal Adaptation)论文的阅读笔记 背景MLA框架实验Q1 与之前的方法相比,MLA能否克服模态懒惰并提高多模态学习性能?Q2 MLA在面临模式缺失的挑战时表现如何?Q3 所有模块是否可以有…...

鸿蒙OS 线程间通信
鸿蒙OS 线程间通信概述 在开发过程中,开发者经常需要在当前线程中处理下载任务等较为耗时的操作,但是又不希望当前的线程受到阻塞。此时,就可以使用 EventHandler 机制。EventHandler 是 HarmonyOS 用于处理线程间通信的一种机制,…...
执行 npm报错 Cannot find module ‘../lib/cli.js‘
报错 /usr/local/node/node-v18.20.4-linux-x64/bin/npm node:internal/modules/cjs/loader:1143 throw err; ^ Error: Cannot find module ../lib/cli.js Require stack: - /usr/local/node/node-v18.20.4-linux-x64/bin/npm at Module._resolveFilename (node:inter…...

基于SpringBoot+Vue+MySQL的国产动漫网站
系统展示 用户前台界面 管理员后台界面 系统背景 随着国内动漫产业的蓬勃发展和互联网技术的快速进步,动漫爱好者们对高质量、个性化的国产动漫内容需求日益增长。然而,市场上现有的动漫平台大多以国外动漫为主,对国产动漫的推广和展示存在不…...
AUTOSAR汽车电子嵌入式编程精讲300篇-基于CAN总线的气动控制
目录 前言 知识储备 什么是气动控制: 气动控制基础知识 一、气动元件 二、气路设计 三、气动控制系统 气动控制系统构成图 气动控制系统基本组成功能图 几种常见的气动执行元件实物图 常用气动压力控制阀实物图 常用气动流动控制阀实物图 电磁控制换向发实物图 部…...

Ubuntu 20.04 内核升级后网络丢失问题的解决过程
在 Ubuntu 系统中,内核升级是一个常见的操作,旨在提升系统性能、安全性和兼容性。然而,有时这一操作可能会带来一些意外的副作用,比如导致网络功能的丧失。 本人本来是想更新 Nvidia 显卡的驱动,使用 ubuntu-drivers …...

论文解读《LaMP: When Large Language Models Meet Personalization》
引言:因为导师喊我围绕 “大语言模型的个性化、风格化生成” 展开研究,所以我就找相关论文,最后通过 ACL 官网找到这篇,感觉还不错,就开始解读吧! “说是解读,其实大部分都是翻译哈哈哈&#x…...

Excel VLOOKUP函数怎么用?vlookup函数的使用方法及案例
大家好,这里是效率办公指南! 🔎 在Excel的世界里,VLOOKUP函数无疑是查询和数据分析中的明星。无论是从庞大的数据表中提取特定信息,还是进行数据的快速匹配,VLOOKUP都能大显身手。今天,我们将深…...

专为汽车功能应用打造的 MLX90376GGO、MLX90377GGO、MLX90377GDC-ADB-280 Triaxis®磁位置传感器 IC
一、MLX90376 Triaxis堆叠式高性能位置传感器芯片(模拟/PWM/SENT/SPC) MLX90376GGO-ABA-600 MLX90376GGO-ABA-630 MLX90376GGO-ABA-680 MLX90376是一款磁性绝对位置传感器芯片,适用于要求具备抗杂散磁场干扰性能的360旋转汽车应用。它提供…...

34.贪心算法1
0.贪心算法 1.柠檬水找零(easy) . - 力扣(LeetCode) 题目解析 算法原理 代码 class Solution {public boolean lemonadeChange(int[] bills) {int five 0, ten 0;for (int x : bills) {if (x 5) // 5 元:直接收下…...

DataX实战:从MongoDB到MySQL的数据迁移--修改源码并测试打包
在现代数据驱动的业务环境中,数据迁移和集成是常见的需求。DataX,作为阿里云开源的数据集成工具,提供了强大的数据同步能力,支持多种数据源和目标端。本文将介绍如何使用DataX将数据从MongoDB迁移到MySQL。 环境准备 安装MongoDB…...

Axure设计之表格列冻结(动态面板+中继器)
在Web端产品设计中,复杂的表格展示是常见需求,尤其当表格包含大量列时,如何在有限的屏幕空间内优雅地展示所有信息成为了一个挑战。用户通常需要滚动查看隐藏列,但关键信息列(如ID、操作按钮等)在滚动时保持…...

WPF DataGrid 动态修改某一个单元格的样式
WPF DataGrid 动态修改某一个单元格的样式 <DataGrid Name"main_datagrid_display" Width"1267" Height"193" Grid.Column"1"ItemsSource"{Binding DataGridModels}"><DataGrid.Columns><!--ElementStyle 设…...
如何安装部署kafka
安装和部署Apache Kafka需要以下几个步骤,包括下载 Kafka、配置 ZooKeeper(或者使用 Kafka 自带的 Kafka Raft 模式替代 ZooKeeper),以及启动 Kafka 服务。以下是一个但基于 Linux 的典型安装流程,可以根据需要改装到其…...

Centos7-rpm包管理器方式安装MySQL 5.7.25
前言 本文用于学习通过Mysql压缩包在centos7中安装和配置的过程以及过程中碰到的Bug解决。 Mysql安装包下载和上传 MySQL :: Download MySQL Community Server (Archived Versions)https://downloads.mysql.com/archives/community/访问Mysql官方下载站,选择对应的…...
Project Online 协作版部署方案
目录 前言 第一部分:为什么选择Project Online? 一、核心优势 二、适用场景 第二部分:部署前的准备工作 一、需求分析 二、账户和权限管理 三、培训与支持 第三部分:Project Online 的核心功能 一、项目创建与管理 二、资源管理 三、团队协作 四、风险管理 五…...

小米 13 Ultra机型工程固件 资源预览与刷写说明 步骤解析
小米 13 Ultra机型---机型代码为ishtar 。工程固件可以辅助修复格机或者全檫除分区后的基带修复。可以用于修复TEE损坏。以及一些分区的底层修复。此款固件也可以为更换UFS后的底包。 通过博文了解 1💝💝💝-----此机型工程固件的资源刷写注意事项 2💝💝💝-----此…...
Goweb预防XSS攻击
XSS攻击示例 假设您有一个简单的Web应用程序,其中包含一个用户输入表单,用户可以在其中输入他们的名字,然后这个名字会被显示在页面上。攻击者可以在表单中输入恶意的JavaScript代码,如,如果应用程序没有对这个输入进…...