分布式锁、Lua脚本、redisson、运行lua脚本优化代码

20240721

  • 一、分布式锁
    • 1. 什么是分布式锁
    • 2. 分布式锁的实现
    • 3. 基于redis的分布式锁
    • 4 总结
  • 二、对于lua脚本可以保证事务,要么成功要么失败。
    • 1. 在redis中调用lua脚本
  • 三、Redisson
    • 1 步骤
    • 2. Redisson的总结
    • 3. 几种分布式锁的区别
  • 三、优化我们的秒杀
    • 1. 我们在创建优惠券的时候,就把他存入redis中,然后对于判断库存和id是否重复下单的操作,我们就在redis中操作
    • 2. 编写lua脚本
    • 3. 在代码里面运行lua脚本

(来源于黑马—太困了,有一些忘了,每天补)

一、分布式锁

1. 什么是分布式锁

因为我们会有多个线程,比如我们的后端服务器有多个,通过nginx进行负载均衡,就会导致我们锁失效,多个服务器都能访问到。
在这里插入图片描述

2. 分布式锁的实现

在这里插入图片描述

3. 基于redis的分布式锁

在这里插入图片描述

4 总结

在这里插入图片描述

二、对于lua脚本可以保证事务,要么成功要么失败。

1. 在redis中调用lua脚本

在这里插入图片描述

三、Redisson

1 步骤

也可以在配置文件中配置,但可能会导致和redis的配置冲突,所以写成配置类。
在这里插入图片描述
在这里插入图片描述

2. Redisson的总结

在这里插入图片描述

3. 几种分布式锁的区别

在这里插入图片描述

三、优化我们的秒杀

在这里插入图片描述

1. 我们在创建优惠券的时候,就把他存入redis中,然后对于判断库存和id是否重复下单的操作,我们就在redis中操作

    @Override@Transactionalpublic void addSeckillVoucher(Voucher voucher) {// 保存优惠券save(voucher);// 保存秒杀信息SeckillVoucher seckillVoucher = new SeckillVoucher();seckillVoucher.setVoucherId(voucher.getId());seckillVoucher.setStock(voucher.getStock());seckillVoucher.setBeginTime(voucher.getBeginTime());seckillVoucher.setEndTime(voucher.getEndTime());seckillVoucherService.save(seckillVoucher);//保存秒杀优惠券的库存到Redis中stringRedisTemplate.opsForValue().set("secKill:stock:" + voucher.getId(), voucher.getStock().toString());}

2. 编写lua脚本

-- 1.参数列表
-- 1.1 优惠券id
local voucherId= ARGV[1]
-- 1.2 用户id
local userId=ARGV[2]-- 2.数据key
-- 2.1 库存key
local stockKey='secKill:stock:'..voucherId -- 连接的时候,是使用..来连接  里面存的是库存
-- 2.2 订单key
local orderKey='secKill:order'..voucherId   --  里面存的是下单人的id-- 3.脚本业务
-- 3.1 判断库存是否充足,get stockKey
if(tonumber(redis.call('get',stockKey)) <=0) then  -- redis.call('get',stockKey)返回的是一个string类型的,无法和0进行比较,所以,转换-- 3.2 库存不足,返回1return 1 -- 什么意思
end
-- 3.3 判断用户是否已经购买过,SISMEMBER orderKye userId   对于set类型 sadd是添加,SISMEMBER是判断是否存在
if(tonumber(redis.call('SISMEMBER',orderKey,userId)) ==1) then--3.4 重复下单,返回2return 2
end
-- 3.5 扣减库存,incrby stockKey -1
redis.call('incrby',stockKey,-1)
-- 3.6 下单,sadd orderKye userId
redis.call('sadd',orderKey,userId)
return 0

3. 在代码里面运行lua脚本

 /*** * 使用lua脚本实现秒杀*/private static final DefaultRedisScript<Long> SECKILL_SCRIPT;//DefaultRedisScript 是 Spring Data Redis 提供的一个类,用于封装 Redis Lua 脚本。在这个上下文中static {
//static { ... }
//这是一个静态初始化块,用于在类加载时初始化 SECKILL_SCRIPT 实例。
//在这个块中,设置了 SECKILL_SCRIPT 的具体属性,包括脚本的位置和结果类型。SECKILL_SCRIPT = new DefaultRedisScript<>();SECKILL_SCRIPT.setLocation(new ClassPathResource("seckill.lua"));SECKILL_SCRIPT.setResultType(Long.class);}/*** 使用lua* @param voucherId* @return*/@Overridepublic Result seckillVoucher(Long voucherId) {//获取用户Long userId= UserHolder.getUser().getId();//1.执行lua脚本Long result = stringRedisTemplate.execute(//总共三个参数,第一个参数是我们的lua脚本,第二个是KEY的参数,第三个是ARGV的参数(有两个)SECKILL_SCRIPT,Collections.emptyList(),//KEY的参数,传一个空集合voucherId.toString(),//ARGV的参数userId.toString());//2.判断结果是否为0int i = result.intValue();//转型if(result!=0){//2.1不为零,没有购买资格return Result.fail(result == 1 ? "库存不足" : "不能重复下单");}//2.2为0,有购买资格,把下单信息保存到阻塞队列long orderId=redisIdWorker.nextId("order");//用我们之前的生成全局唯一的订单id方法生成订单//TODO 保存到阻塞队列//3.返回订单idreturn Result.ok(orderId);}

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

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

相关文章

Docker安装笔记

1. Mac安装Docker 1.1 Docker安装包下载 1.1.1 阿里云 对于10.10.3以下的用户 推荐使用 对于10.10.3以上的用户 推荐使用 1.1.2 官网下载 系统和芯片选择适合自己的安装包 1.2 镜像加速 【推荐】阿里镜像 登陆后&#xff0c;左侧菜单选中镜像加速器就可以看到你的专属地…

windows和linux的等保加固测评的经验分享

一头等保加固测评的牛马&#xff0c;需要能做到一下午测评n个服务器 接下来就讲讲如何当一头xxxxxxxxx》严肃的等保测评加固的经验分享&#xff08; 一、window等保 首先你要自己按着教程在虚拟机做过一遍&#xff08;win2012和win2008都做过一遍&#xff0c;大概windows的…

pico+unity3d 射线交互教程

前期配置&#xff1a;环境配置参考教程一&#xff0c;手部模型参考教程二&#xff0c;场景基于上一篇搭建。 最终效果&#xff1a;手部射线&#xff08;初始不可见&#xff09;对准 UI 显示&#xff0c;按下手柄 Trigger 键与可交互 UI&#xff08;如 Button、Toggle、Slider …

论文解读 | ICML2024:突破Transformer上下文学习中的瓶颈

点击蓝字 关注我们 AI TIME欢迎每一位AI爱好者的加入&#xff01; 作者简介 付靖文&#xff0c;西安交通大学博士生 简介 上下文学习&#xff0c;即从上下文示例中学习&#xff0c;是Transformer一项令人印象深刻的能力。然而&#xff0c;由于学习瓶颈的出现——在训练过程中模…

移动UI:任务中心的作用,该如何设计更合理?

任务中心是移动应用中用于展示和管理用户待办任务、提醒事项、用户福利、打卡签到等内容的功能模块。合理设计任务中心可以提升用户体验和工作效率。 以下是一些设计任务中心的合理建议&#xff1a; 1. 易于查看和管理&#xff1a; 任务中心的设计应该使用户能够快速、直观地…

C# 实现跨进程条件变量

C# 进程通信系列 第一章 共享内存 第二章 条件变量&#xff08;本章&#xff09; 第三章 消息队列 文章目录 C# 进程通信系列前言一、关键实现1、用到的主要对象2、初始化区分创建和打开3、变量放到共享内存4、等待和释放逻辑 二、完整代码三、使用示例1、同步控制2、跨进程控…

202496读书笔记|《飞花令·菊(中国文化·古典诗词品鉴)》——荷尽已无擎雨盖,菊残犹有傲霜枝

202496读书笔记|《飞花令菊&#xff08;中国文化古典诗词品鉴&#xff09;》——荷尽已无擎雨盖&#xff0c;菊残犹有傲霜枝 《飞花令菊&#xff08;中国文化古典诗词品鉴&#xff09;》素心落雪 编著。飞花令得名于唐代诗人韩翃《寒食》中的名句“春城无处不飞花”&#xff0c…

KubeSphere核心实战_kubesphere全功能安装_启用kubesphere的热插拔插件---分布式云原生部署架构搭建037

然后我们开始安装kubesphere,首先进入官网点击kubernetes安装 可以看到对应的,条件说kubernetes要在1.20.x以上,我们的是 1.20.9,然后cpu硬件满足,然后,默认存储类型,上一节我们安装好了 然后就可以开始,去下载两个配置文件可以看到上面的两个配置文件 这两个文件,上面是直接…

跨域问题:预检请求

解决跨域问题之预检请求 预检请求&#xff08;Preflight Request&#xff09;是跨域资源共享&#xff08;CORS&#xff09;中用于安全检查的一种机制。 它是由浏览器自动发起的一个OPTIONS请求&#xff0c;目的是在实际跨域请求之前&#xff0c;询问服务器是否允许这次跨域操…

学习TS -类型

let a:number10;//数值型 let b:string"zhaoya";//字符串型 let c:booleantrue;//布尔类型 let d:10;//字面量 let e:any10;//任意类型&#xff0c;可以给别人赋值&#xff0c;而且不会提示报错 let f:unknown50;//未知类型&#xff0c;他给别人赋值&#xff0c;赋值…

kafka开启kerberos和ACL

作者&#xff1a;恩慈 一、部署kafka-KB包 1&#xff0e;上传软件包 依次点击 部署中心----部署组件----上传软件包 选择需要升级的kafka版本并点击确定 2&#xff0e;部署kafka 依次点击部署中心----部署组件----物理/虚拟机部署----选择集群----下一步 选择手动部署-…

消费金融系统开发回忆录

架构设计图 整个支付链路上的功能 支付系统应该有&#xff1a;账户管理、渠道管理、支付管理、对账管理、清算管理、结算管理 一笔支付订单&#xff0c;在支付系统侧就是要记录清楚&#xff0c;谁发起的、对哪个商品进行支付、通过哪个渠道支付、支付时间、支付结果等…

C++基础入门(二)(函数重载,引用,内联函数,nullptr)

目录 一. 函数重载 1. 概念 2. 实现 (1). 参数类型不同 (2). 参数个数不同 (3). 参数类型顺序不同 3. 注意事项 (1). 返回值不能作为重载的条件 (2). 不能仅按函数返回类型重载 (3). 与缺省参数的问题 二. 引用 1. 概念和定义 2. 引用的特性 (1). 引用在定义时必须…

LDR6020双盲插便携显示器应用

随着USB Type-C接口的普及&#xff0c;越来越多的手机和笔记本电脑都支持通过C接口输出视频。这个小巧而精密的接口&#xff0c;大有把传统的HDMI和DisplayPort接口取而代之的架势。特别是usb4的推出&#xff0c;更是为USB TYPE-C接口一统有线接口形态奠定了基础。 单USB-C接口…

python入门课程Pro(1)--数据结构及判断

数据结构及判断 第1课 复杂的多向选择1.if-elif-else2.if嵌套3.练习题&#xff08;1&#xff09;大招来了&#xff08;2&#xff09;奇数还是偶数&#xff08;3&#xff09;简洁代码 第2课 数据与判断小结1.变量2.格式化输出3.逻辑运算-或与非4.判断条件5.练习题&#xff08;1&…

【手撕数据结构】拿捏双向链表

目录 链表介绍初始化链表销毁链表查找节点打印链表增加节点尾插头插在指定位置之后插入节点 删除节点尾删头删删除指定位置节点 链表判空 链表介绍 前面说到&#xff0c;链表的结构一共有八种&#xff1a;带头单向循环链表、带头单向非循环链表、带头双向循环链表、带头双向非…

【初阶数据结构】5.栈和队列

文章目录 1.栈1.1 概念与结构1.2 栈的实现2.队列2.1 概念与结构2.2 队列的实现3.栈和队列算法题3.1 有效的括号3.2 用队列实现栈3.3 用栈实现队列3.4 设计循环队列 1.栈 1.1 概念与结构 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操…

C语言宏定义格式化控制台打印

写了个简单的控制台打印代码&#xff0c;有三种打印级别 DEBUG INFO ERROR&#xff0c;支持颜色打印&#xff0c;支持时间打印 在MSVC环境中使用 #include <time.h> #include <string.h> #include <stdio.h>/* log level */ #define LOG_LEVEL_DEBUG (1) #d…

【STM32 HAL库】全双工I2S+双缓冲DMA的使用

1、配置I2S 我们的有效数据是32位的&#xff0c;使用飞利浦格式。 2、配置DMA **这里需要注意&#xff1a;**i2s的DR寄存器是16位的&#xff0c;如果需要发送32位的数据&#xff0c;是需要写两次DR寄存器的&#xff0c;所以DMA的外设数据宽度设置16位&#xff0c;而不是32位。…

一文带你读懂MLIR论文,理解MLIR设计准则.

论文MLIR: Scaling Compiler Infrastructure for Domain Specific Computation MLIR&#xff1a;针对特定领域计算扩展编译器基础设施 文章目录 论文MLIR: Scaling Compiler Infrastructure for Domain Specific Computation1. 论文下载2. TVM关于MLIR的讨论3. 论文正文0. 摘要…