当前位置: 首页 > news >正文

分布式锁-Redisson实现

       

目录

本地锁的局限性

Redisson解决分布式锁问题

         


        在分布式环境下,分布式锁可以保证在多个节点上的并发操作时数据的一致性和互斥性。分布式锁有多种实现方案,最常用的两种方案是:zookeeper和redis,本文介绍redis实现分布式锁方案。

本地锁的局限性

        JDK中自带的synchronized及lock锁,这些锁都是本地锁,在一个节点服务(一个JVM)下可以实现“锁”的效果,一旦服务多实例,本地锁就会存在问题。下方示例演示并发对redis的值做自增操作,观察效果,步骤如下:

        1、编写请求和服务接口

        此代码的主要逻辑是redis中key=num的值每次+1(初始值是0),其中redisTest方法上加上本地锁(synchronized)

@GetMapping("/redisTest")
public GenericWebResult redisTest() {Long result = this.blogContentService.redisTest();log.info("设置redis中num值:{}",result);return GenericWebResult.ok((Object) "测试成功",result);
}
@Override
public synchronized Long redisTest() throws BusinessException {Long result = 0l;String key = "num";RBucket<Object> bucket = this.redissonClient.getBucket(key);if(bucket != null) {Long ori = (Long)bucket.get();result = ori.longValue() + 1;this.redissonClient.getBucket(key).set(result);}return result;
}

        2、单个实例启动后,用jemter并发请求测试 

        单实例启动后,服务端口:8888,jemter通过100个线程并发请求访问后,redis中key=num的值是100,符合预期。

 

        3、后台服务启动多个实例, 再次用jemter并发请求测试 

        后台服务启动了2个实例,端口分别是8888和9999,并通过网关gateway对外公布统一的请求地址,网关会自动均衡到端口是8888和9999的2个服务中(这部分的配置不在此文赘述,详情见网关Gateway-CSDN博客),网关服务的端口是7777,请求的统一地址是:http://localhost:7777/blog-content/blogContent/redisTest ,通过jmeter测试如下(num初始恢复到0):

        执行后,发现redis中key=num的值变成了65,不是100,不符合预期,证明本地锁在分布式环境下是有局限性的,它只能保证在一个JVM下锁的有效性。

Redisson解决分布式锁问题

        Redisson是一个在Redis的基础上实现的Java驻内存数据网格(In-Memory Data Grid)。它不仅提供了一系列的分布式的Java常用对象,还提供了许多分布式服务,其中就包含了各种分布式锁的实现。使用Redisson实现分布式锁,需要如下步骤:

        1、项目添加依赖

<!-- redisson -->
<dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId><exclusions><exclusion><groupId>org.redisson</groupId><artifactId>redisson-spring-data-23</artifactId></exclusion></exclusions>
</dependency>
<dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-data-26</artifactId><version>3.47.0</version>
</dependency>

        2、改造redisTest方法,引入锁

        通过redissonClient.getLock获取锁,在执行业务逻辑前锁住lock.lock(),执行完业务逻辑后释放锁lock.unlock()

@Override
public Long redisTest() throws BusinessException {Long result = 0l;RLock lock = redissonClient.getLock("lock");lock.lock();//业务逻辑try {log.info("业务逻辑开始...");Thread.sleep(1000);//模拟业务逻辑时长String key = "num";RBucket<Object> bucket = this.redissonClient.getBucket(key);if(bucket != null) {Long ori = (Long)bucket.get();result = ori.longValue() + 1;this.redissonClient.getBucket(key).set(result);}log.info("业务逻辑结束...");} catch (InterruptedException e) {e.printStackTrace();} finally {lock.unlock();log.info("redis 解锁...");}return result;
}

        3、和第一章节一样,后台服务同样启动2个实例,端口分别是8888和9999,用jmeter模拟并发请求网关端口。

 

        从后台请求日志可以看出,2个服务每隔1秒获取到锁,然后执行业务逻辑(num++),最终num的值是100,符合预期,实现了分布式环境下锁的效果。

 

        

        

        

        

         

        

http://www.lqws.cn/news/179389.html

相关文章:

  • MySQL查询语句
  • C++11:原子操作与内存顺序:从理论到实践的无锁并发实现
  • table表格合并,循环渲染样式
  • React项目的状态管理:Redux Toolkit
  • kubeadm安装k8s
  • 黄晓明新剧《潜渊》定档 失忆三面间谍开启谍战新维度
  • 极空间z4pro配置gitea mysql,内网穿透
  • pgsql:还原数据库后出现重复序列导致“more than one owned sequence found“报错问题的解决
  • 网页端 js 读取发票里的二维码信息(图片和PDF格式)
  • 32单片机——窗口看门狗
  • 五子棋测试用例
  • go语言学习 第6章:错误处理
  • 浏览器工作原理05 [#] 渲染流程(上):HTML、CSS和JavaScript是如何变成页面的
  • Java逻辑运算符常见错误分析与规避指南
  • 03 mysql 的环境搭建
  • 服务器磁盘空间被Docker容器日志占满处理方法
  • 服务器信任质询
  • 什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南
  • 服务器出现故障怎么办?快速排查与解决方法
  • PostgreSQL 的扩展pg_freespacemap
  • Linux操作系统之进程(五):初识地址空间
  • Edge(Bing)自动领积分脚本部署——基于python和Selenium(附源码)
  • 七、数据库的完整性
  • Codeforces EDU Round 179 A~D
  • PDF转Markdown/JSON软件MinerU最新1.3.12版整合包下载
  • HarmonyOS运动语音开发:如何让运动开始时的语音播报更温暖
  • Redis 主从 + 哨兵集群部署
  • 【HarmonyOS 5】出行导航开发实践介绍以及详细案例
  • 《深度探秘:Java构建Spark MLlib与TensorFlow Serving混合推理流水线》
  • 麒麟系统使用-进行.NET开发