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

[Redis实战]分布式锁-redission

五、分布式锁-redission

5.1 分布式锁-redission功能介绍

基于setnx实现的分布式锁存在下面的问题:

重入问题:重入问题就是指获得锁的线程可以再次进入到相同的锁的代码中,可重入锁的意义在于防止死锁。比如HashTable这样的代码中,他的方法都是使用synchronized修饰的,假如他在一个方法内,调用另一个方法,那么此时如果是不可重入的,不就死锁了吗?所以可重入锁他的主要意义是防止死锁,我们的synchronized和Lock锁都是可重入的。

不可重试:是指目前的分布式只能尝试一次,我们认为合理的情况是:当线程在获得锁失败后,他应该再次尝试获得锁。

超时释放:我们在加锁时增加了过期时间,这样的我们可以防止死锁,但是如果卡顿的时间过长,虽然我们采用了lua表达式防止删锁的时候误删别人的锁,但是毕竟没有锁住,有安全隐患。

主从一致性:如果Redis提供了主从集群,当我们向集群写数据时,主机需要异步的将数据同步给从机,而在同步过去之前,主机如果宕机了,就会出现死锁问题。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Redission是一个在Redis的基础上实现的Java驻内存数据网格。它不仅提供了一系列的分布式的Java常用对象,还提供了许多分布式服务,其中就包含了各种分布式锁的实现。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

5.2 分布式锁-Redisson快速入门

引入依赖:

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

配置Redisson客户端:

@Configuration
public class RedissonConfig {@Beanpublic RedissonClient redissonClient() {//配置Config config = new Config();config.useSingleServer().setAddress("redis://192.168.88.151:6379").setPassword("030522");//创建RedissonClient对象return Redisson.create(config);}
}

如何使用Redission的分布式锁

@Resource
private RedissionClient redissonClient;@Test
void testRedisson() throws Exception{//获取锁(可重入),指定锁的名称RLock lock = redissonClient.getLock("anyLock");//尝试获取锁,参数分别是:获取锁的最大等待时间(期间会重试),锁自动释放时间,时间单位boolean isLock = lock.tryLock(1,10,TimeUnit.SECONDS);//判断获取锁成功if(isLock){try{System.out.println("执行业务");          }finally{//释放锁lock.unlock();} }    
}

在 VoucherOrderServiceImpl中注入RedissonClient

@Resource
private RedissonClient redissonClient;@Override
public Result seckillVoucher(Long voucherId) {// 1.查询优惠券SeckillVoucher voucher = seckillVoucherService.getById(voucherId);// 2.判断秒杀是否开始if (voucher.getBeginTime().isAfter(LocalDateTime.now())) {// 尚未开始return Result.fail("秒杀尚未开始!");}// 3.判断秒杀是否已经结束if (voucher.getEndTime().isBefore(LocalDateTime.now())) {// 尚未开始return Result.fail("秒杀已经结束!");}// 4.判断库存是否充足if (voucher.getStock() < 1) {// 库存不足return Result.fail("库存不足!");}Long userId = UserHolder.getUser().getId();//创建锁对象 这个代码不用了,因为我们现在要使用分布式锁//SimpleRedisLock lock = new SimpleRedisLock("order:" + userId, stringRedisTemplate);RLock lock = redissonClient.getLock("lock:order:" + userId);//获取锁对象boolean isLock = lock.tryLock();//加锁失败if (!isLock) {return Result.fail("不允许重复下单");}try {//获取代理对象(事务)IVoucherOrderService proxy = (IVoucherOrderService) AopContext.currentProxy();return proxy.createVoucherOrder(voucherId);} finally {//释放锁lock.unlock();}}

5.3 分布式锁-redisson可重入锁原理

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 可重入:利用hash结构记录线程id和重入次数
  • 可重试:利用信号量和PubSub功能实现等待、唤醒,获取锁失败的重试机制
  • 超时续约:利用watchDog,每隔一段时间(releaseTime/),重置超时时间
  • multiLock:多个独立的Redis节点,必须在所有节点都获取重入锁,才算获取锁成功。运维成本高、实现复杂。

相关文章:

  • 在云服务器ECS上用Python写一个搜索引擎
  • 【PostgreSQL】表操作-表权限
  • 利用计算机名称共享打印机步骤,如何连接共享打印机汇总教程
  • docker 使用
  • 【Kubernetes】Kubernetes ConfigMap 实战指南
  • 经典八股文之RocketMQ
  • three.js Raycaster(鼠标点击选中模型)
  • Vue开发中使用Element UI过程中遇到的问题及解决方案Missing required prop: “value”
  • Vue-2、初识Vue
  • leetcode 每日一题 2024年01月01日 经营摩天轮的最大利润
  • insert into select简单数据迁移-postgresql
  • springboot中引入AOP切面编程
  • 万界星空科技云MES,助力客户快速构建数字工厂
  • 在k8s集群中部署多nginx-ingress
  • Centos7.9或Deebian12安装K3s和k9s详细流程
  • JS中 map, filter, some, every, forEach, for in, for of 用法总结
  • 分享的文章《人生如棋》
  • 【技术性】Search知识
  • 77. Combinations
  • classpath对获取配置文件的影响
  • electron原来这么简单----打包你的react、VUE桌面应用程序
  • es6要点
  • IDEA 插件开发入门教程
  • Invalidate和postInvalidate的区别
  • Javascript弹出层-初探
  • Java新版本的开发已正式进入轨道,版本号18.3
  • MobX
  • python_bomb----数据类型总结
  • React+TypeScript入门
  • Travix是如何部署应用程序到Kubernetes上的
  • 测试开发系类之接口自动化测试
  • 产品三维模型在线预览
  • 巧用 TypeScript (一)
  • 容器化应用: 在阿里云搭建多节点 Openshift 集群
  • 说说动画卡顿的解决方案
  • 腾讯优测优分享 | 你是否体验过Android手机插入耳机后仍外放的尴尬?
  • 微信小程序实战练习(仿五洲到家微信版)
  • 小程序01:wepy框架整合iview webapp UI
  • zabbix3.2监控linux磁盘IO
  • 测评:对于写作的人来说,Markdown是你最好的朋友 ...
  • ​你们这样子,耽误我的工作进度怎么办?
  • ​软考-高级-信息系统项目管理师教程 第四版【第14章-项目沟通管理-思维导图】​
  • #includecmath
  • #pragma 指令
  • (14)学习笔记:动手深度学习(Pytorch神经网络基础)
  • (javascript)再说document.body.scrollTop的使用问题
  • (Redis使用系列) Springboot 实现Redis 同数据源动态切换db 八
  • (八十八)VFL语言初步 - 实现布局
  • (读书笔记)Javascript高级程序设计---ECMAScript基础
  • (二)c52学习之旅-简单了解单片机
  • (二)WCF的Binding模型
  • (附源码)ssm考试题库管理系统 毕业设计 069043
  • (含react-draggable库以及相关BUG如何解决)固定在左上方某盒子内(如按钮)添加可拖动功能,使用react hook语法实现
  • (论文阅读30/100)Convolutional Pose Machines
  • (续)使用Django搭建一个完整的项目(Centos7+Nginx)