Redis实现分布式锁的进阶版:Redisson实战指南

一、为什么选择Redisson?

在上一篇文章中,我们通过Redis原生命令实现了分布式锁。但在实际生产环境中,这样的基础方案存在三大痛点:

  1. 锁续期难题:业务操作超时导致锁提前释放
  2. 不可重入限制:同一线程无法重复获取已持有的锁
  3. 高可用风险:单点故障可能导致锁失效

Redisson作为Redis官方推荐的Java客户端,提供了开箱即用的分布式锁实现,其核心优势在于:

  • 自动续期机制(看门狗)
  • 可重入锁支持
  • 多种锁类型(公平锁、联锁等)
  • 完善的异常处理

二、快速集成Redisson

2.1 引入依赖

在Maven项目中添加依赖:

<dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.23.2</version>
</dependency>

2.2 配置连接(Spring Boot示例)

@Configuration
@ConfigurationProperties(prefix = "spring.redis")
public class RedissonConfig {private String host;private String password;private int port;@Beanpublic RedissonClient redissonClient() {Config config = new Config();config.useSingleServer().setAddress("redis://" + host + ":" + port).setPassword(password).setTimeout(3000);return Redisson.create(config);}
}

配置说明

  • address格式:redis://IP:PORT 或 rediss://IP:PORT(SSL加密)
  • timeout:操作超时时间(毫秒)

三、Redisson分布式锁核心API

3.1 基础锁操作

// 获取锁对象
RLock lock = redissonClient.getLock("orderLock");// 阻塞式获取锁(默认30秒有效期,自动续期)
lock.lock();// 尝试获取锁(等待10秒,锁持有15秒)
boolean res = lock.tryLock(10, 15, TimeUnit.SECONDS);// 释放锁
lock.unlock();

3.2 看门狗机制原理

当使用无参lock()方法时:

  1. 默认设置锁过期时间30秒
  2. 启动后台线程每10秒检查一次
  3. 如果线程仍持有锁,自动续期到30秒

3.3 三种加锁方式对比

方法签名特点适用场景
void lock()阻塞等待,自动续期长期持有锁场景
boolean tryLock()立即返回结果快速失败场景
boolean tryLock(long waitTime, …)可设置等待时间,手动控制有效期精确控制锁持有时间的业务

四、实战:司机抢单系统

4.1 业务场景分析

假设网约车系统中:

  • 多个司机同时抢同一个订单
  • 订单状态变更需要原子操作
  • 高并发下需保证数据一致性

4.2 分布式锁实现方案

public Boolean robOrder(Long driverId, Long orderId) {final String lockKey = RedisConstant.ROB_ORDER_LOCK + orderId;RLock lock = redissonClient.getLock(lockKey);try {// 尝试获取锁(最多等待2秒,锁持有5秒)if (lock.tryLock(2, 5, TimeUnit.SECONDS)) {// 二次校验订单状态if (!redisTemplate.hasKey(ORDER_AVAILABLE_KEY)) {throw new BusinessException("订单已被抢");}// 执行核心业务逻辑updateOrderStatus(driverId, orderId);// 移除可用标记redisTemplate.delete(ORDER_AVAILABLE_KEY);return true;}return false;} catch (InterruptedException e) {Thread.currentThread().interrupt();throw new BusinessException("系统中断异常");} finally {// 仅释放当前线程持有的锁if (lock.isHeldByCurrentThread()) {lock.unlock();}}
}

4.3 关键代码解析

  1. 锁命名策略

    • 使用订单ID作为锁后缀,实现细粒度控制
    • 示例:rob_order_lock:20230815001
  2. 双重检查机制

    • 获取锁前快速失败
    • 获取锁后再次校验业务状态
  3. 异常处理规范

    • 正确处理InterruptedException
    • finally块确保锁释放

五、生产环境最佳实践

5.1 锁使用原则

原则说明反例
最小作用域原则锁的粒度尽可能小对整个系统使用全局锁
快速释放原则业务完成后立即释放锁持有锁进行网络调用等耗时操作
异常处理原则finally块确保锁释放未处理异常导致死锁
避免嵌套原则谨慎使用嵌套锁多层级锁增加死锁风险

5.2 常见问题解决方案

问题一:锁续期时间设置不合理

  • 症状:频繁出现锁过期
  • 方案:根据业务耗时动态调整
// 根据历史统计设置合理值
long leaseTime = calculateBusinessTime() + 5; // 增加5秒缓冲
lock.tryLock(2, leaseTime, TimeUnit.SECONDS);

问题二:客户端时钟不同步

  • 症状:锁提前/延后释放
  • 方案:启用NTP时间同步服务

问题三:Redis集群故障转移

  • 症状:脑裂导致多客户端持有锁
  • 方案:使用RedLock算法
RLock lock1 = redissonClient1.getLock("lock");
RLock lock2 = redissonClient2.getLock("lock");
RLock lock3 = redissonClient3.getLock("lock");RedissonRedLock redLock = new RedissonRedLock(lock1, lock2, lock3);
redLock.lock();

六、性能优化建议

  1. 连接池配置
// 在Redisson配置中优化连接参数
config.useSingleServer().setConnectionPoolSize(64)  // 连接池大小.setConnectionMinimumIdleSize(24); // 最小空闲连接
  1. 监控指标收集
  • 锁等待时间
  • 锁持有时间
  • 锁竞争频率
  1. 压力测试方案
// 使用JMeter模拟并发场景
ThreadGroup:Number of Threads: 100Ramp-Up Period: 5s
Loop Controller:Loop Count: Forever

七、扩展应用场景

7.1 分布式限流

RRateLimiter rateLimiter = redisson.getRateLimiter("apiLimit");
// 每秒处理10个请求
rateLimiter.trySetRate(RateType.OVERALL, 10, 1, RateIntervalUnit.SECONDS);

7.2 分布式信号量

RSemaphore semaphore = redisson.getSemaphore("parkingSlot");
// 获取停车位(最多等待10秒)
if(semaphore.tryAcquire(10, TimeUnit.SECONDS)) {try {// 停车操作} finally {semaphore.release();}
}

八、总结与展望

通过Redisson实现分布式锁,开发者可以:

  • 避免手动处理复杂边界条件
  • 获得生产级的可靠性保证
  • 轻松扩展更多分布式功能

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/80729.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大语言模型 12 - 从0开始训练GPT 0.25B参数量 MiniMind2 补充 训练开销 训练步骤 知识蒸馏 LoRA等

写在前面 GPT&#xff08;Generative Pre-trained Transformer&#xff09;是目前最广泛应用的大语言模型架构之一&#xff0c;其强大的自然语言理解与生成能力背后&#xff0c;是一个庞大而精细的训练流程。本文将从宏观到微观&#xff0c;系统讲解GPT的训练过程&#xff0c;…

SID 2025上的天马,用“好屏”技术重构产业叙事

作为全球最具影响力的显示行业盛会&#xff0c;SID国际显示周不仅是技术比拼的舞台&#xff0c;更是未来产业方向的风向标。SID 2025上的技术密度与产业动态&#xff0c;再一次验证了这一定律。 Micro-LED、柔性OLED、裸眼3D、量子点、透明显示等新技术在SID 2025集中亮相&…

【AI News | 20250520】每日AI进展

AI Repos 1、nanoDeepResearch nanoDeepResearch 是一个受 ByteDance 的 DeerFlow 项目启发&#xff0c;旨在从零开始构建深度研究代理的后端项目。它不依赖 LangGraph 等现有框架&#xff0c;通过实现一个 ReAct 代理和状态机来模拟 Deep Research 的工作流程。项目主要包含规…

钉钉开发之AI消息和卡片交互开发文档收集

AI消息和卡片交互开发文档 智能交互接口能力介绍 AI助理发消息&#xff08;主动直接发送模式 AI 助理发消息 - 主动发送模式 AI 助理发消息 - 回复消息模式 AI 助理发消息 - Webhook 回复消息模式 Stream 模式响应卡片回传请求事件 upload-media-files AI 助理发消息&a…

Redis中的事务和原子性

在 Redis 中&#xff0c;事务 和 原子性 是两个关键概念&#xff0c;用于保证多个操作的一致性和可靠性。以下是 Redisson 和 Spring Data Redis 在处理原子性操作时的区别与对比&#xff1a; 1. Redis 的原子性机制 Redis 本身通过以下方式保证原子性&#xff1a; 单线程模型…

Apollo10.0学习——planning模块(8)之scenario、Stage插件详解二

scenario插件 插件总览插件ValetParkingScenario阶段一&#xff1a;StageApproachingParkingSpotprocess()方法 阶段二&#xff1a;StageParkingprocess()方法FinishStage方法 插件PullOverScenarioIsTransferable: 场景切入条件 代码逻辑阶段一&#xff1a;PullOverStageAppro…

JVM的面试相关问题

面试中的相关问题主要是三块 1.JVM 内存区域划分 2.JVM 的类加载机制 3.JVM 的垃圾回收机制 JVM Java虚拟机 VM Virtual Machine 虚拟机,用 软件 来 模拟 硬件 传统意义上的"虚拟机" 更多指的是 VMWare, Virtual Box, Hyper-V, KVM(构造出虚拟的电脑,甚至可以…

win10使用nginx做简单负载均衡测试

一、首先安装Nginx&#xff1a; 官网链接&#xff1a;https://nginx.org/en/download.html 下载完成后&#xff0c;在本地文件中解压。 解压完成之后&#xff0c;打开conf --> nginx.config 文件 1、在 http 里面加入以下代码 upstream GY{#Nginx是如何实现负载均衡的&a…

[特殊字符]车牌识别相机,到底用在哪?

停车场管理&#xff0c;快速通行不是梦 停车场大概是车牌识别相机最常见的 “工作岗位” 啦&#xff01;以前进出停车场&#xff0c;取卡、刷卡、人工收费&#xff0c;一系列操作下来&#xff0c;高峰期的时候真的能把人等得不耐烦&#x1f62b; 现在有了车牌识别相机&#xff…

nosqlbooster pojie NoSQLBooster for MongoDB

测过可用&#xff0c;注意 asar的安装使用报错改用 npx asar extract app.asar app 路径 C:\Users{computerName}\AppData\Local\Programs\nosqlbooster4mongo\resources npm install asar -g asar extract app.asar app 打开shared\lmCore.js 修改MAX_TRIAL_DAYS3000 修改…

组态王通过开疆智能profinet转ModbusTCP网关连接西门子PLC配置案例

本案例是组态王通过使用开疆智能研发的Profinet转ModbusTCP网关采集西门子1200PLC中数据的案例。 网关配置 首先来配置网关的参数&#xff0c;打开网关配置软件“Gateway Configuration Studio” 由于组态王那侧设定为ModbusTCP客户端所以网关作为ModbusTCP服务器。新建项目…

大模型服务如何实现高并发与低延迟

写在前面 大型语言模型(LLM)正以前所未有的速度渗透到各行各业,从智能客服、内容创作到代码生成、企业知识库,其应用场景日益丰富。然而,将这些强大的 AI 能力转化为稳定、高效、可大规模应用的服务,却面临着巨大的挑战,其中高并发处理能力和低响应延迟是衡量服务质量的…

k8s监控方案实践补充(二):使用kube-state-metrics获取资源状态指标

k8s监控方案实践补充&#xff08;二&#xff09;&#xff1a;使用kube-state-metrics获取资源状态指标 文章目录 k8s监控方案实践补充&#xff08;二&#xff09;&#xff1a;使用kube-state-metrics获取资源状态指标一、Metrics Server简介二、kube-state-metrics实战部署1. 创…

Manus 全面开放注册,OpenAI 发布 Codex,ChatGPT 上线 GPT-4.1!| AI Weekly 5.12-18

&#x1f4e2;本周 AI 快讯 | 1 分钟速览&#x1f680; 1️⃣ &#x1f4dd; Manus 全面开放注册 &#xff1a;无需邀请码即可注册&#xff0c;新用户免费获得 1000 积分&#xff0c;每日 300 积分免费任务。 2️⃣ &#x1f50d; 阿里 Qwen 推出「深入研究」 &#xff1a;Qw…

代理(主要是动态)和SpringAOP

代理 静态代理基于继承实现动态代理是基于接口实现 业务层每次实现转账都需要执行&#xff0c;可以把他们拿出来当成一个切面&#xff0c;自己写出一个代理类&#xff0c;让业务层只执行业务的逻辑&#xff0c;重复的代码代理类来完成&#xff0c;然后调用代理类来执行。 代理类…

uniapp打包H5,输入网址空白情况

由于客户预算有限&#xff0c;最近写了两个uniapp打包成H5的案例&#xff0c;总结下面注意事项 1. 发行–网站-PCWeb或手机H5按钮&#xff0c;输入名称&#xff0c;网址 点击【发行】&#xff0c;生成文件 把这个给后端&#xff0c;就可以了 为什么空白呢 最重要一点&#xf…

uniapp-商城-63-后台 商品列表(分类展示商品的删除)

商品列表中的数据需要进行状态管理&#xff0c;如上架、下架、删除和修改等操作。对于存在错误或后期需要重新上传的商品&#xff0c;可以通过删除操作进行处理。 具体到商品删除功能的实现&#xff0c;其基本流程如下&#xff1a;用户在前端页面点击删除按钮后&#xff0c;系统…

学习设计模式《十》——代理模式

一、基础概念 代理模式的本质【控制对象访问】&#xff1b; 代理模式的定义&#xff1a;为其他对象提供一种代理以控制对这个对象的访问&#xff1b; 代理模式的功能&#xff1a;代理模式是通过创建一个代理对象&#xff0c;用这个代理对象去代表真实的对象&#xff1b;客户端得…

阿里云web端直播(前端部分)

阿里云&#xff1a;Web播放器快速接入_视频点播(VOD)-阿里云帮助中心 import Aliplayer from aliyun-aliplayerimport aliyun-aliplayer/build/skins/default/aliplayer-min.css<div id"J_prismPlayer" style"width: 300px; height: 300px;" />var …

深入解析OrientDB:多模型数据库的技术优势与实际应用

OrientDB 是一款开源的多模型 NoSQL 数据库&#xff0c;融合了文档数据库、图数据库和对象数据库的特性。它不仅支持灵活的数据建模&#xff0c;还提供了高性能的查询能力&#xff0c;适用于社交网络、物联网、内容管理等场景。本文详细探讨 OrientDB 的核心特性、应用场景&…