14. Redisson 分布式锁

news2024/10/6 8:32:19

Spring Cloud 微服务系列文章,点击上方合集↑

1. 开头

在单体应用中,我们可以用Java的synchronizedlock来使用锁,但在微服务的场景下,一个应用会部署多个实例,就需要保证多个实例的多个线程同时只能有一个线程来操作资源,那就需要分布式锁,

Redisson分布式锁的基本原理是通过Redis的setnx命令实现的。当一个进程需要获取锁时,通过调用Redis的setnx命令,在Redis中创建一个key表示锁的名称,如果成功地创建了这个
key,则表示获取锁成功,可以执行相应的业务逻辑。如果创建key失败,则表示锁已经被其他进程获取了,当前进程需要等待直到获取到锁为止。当执行完业务逻辑后,需要释放锁,即通过Redisdel命令删除锁的key,这样其他进程就可以获取到锁了。

举个通俗的栗子:你上厕所的时候推一下门看看里面有没有人(尝试获取锁),里面有人你需要在门口等着(等待锁),当他上完后开门了(释放锁),你进去的时候把门关上了(上锁),你执行完脱裤子、拉屎、提裤子等操作后把门打开了(释放锁)。

本文我们将通过抢购茅台的例子来进行演示。

抢购茅台分为三个步骤:

  1. 判断库存是否充足
  2. 创建新订单
  3. 扣减库存。

2. 安装运行Redis

Redisson是基于Redis的,我们需要先下载运行Redis

Redis是内存数据库,Redisson = Redis + son(儿子)。

2.1 Windows

  • github下载地址:https://github.com/redis-windows/redis-windows/releases

  • github下载很慢,网盘下载(推荐):
    「Redis-7.0.8-Windows-x64.zip」来自UC网盘分享
    https://drive.uc.cn/s/4087d341fd084

启动Redis

# 启动服务
redis-server.exe redis.conf

# 老版本的配置文件名称
redis-server.exe redis.windows.conf
  • 需要指定redis.conf配置文件,可以在redis.conf文件中设置端口、密码等。

进入Redis命令行界面

# redis命令行界面
redis-cli.exe

# 设置键值对
set mykey hello
# 获取值
get mykey

2.2 Linux

以CentOS为例,通过yum命令安装。

# 安装
sudo yum install redis

# 启动
sudo systemctl start redis

# 进入redis命令行界面
redis-cli
# 设置键值对
set mykey hello
# 获取值
get mykey

3. 业务SQL脚本

执行如下SQL脚本

  • 生成商品表product
  • 生成商品订单表product_order
  • 商品表插入一条记录,贵州茅台总数量100瓶
CREATE TABLE `product` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键id',
  `name` varchar(20) NOT NULL DEFAULT '' COMMENT '商品名称',
  `number` int(11) NOT NULL DEFAULT 0 COMMENT '商品数量',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE `product_order` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键id',
  `product_id` bigint(20) DEFAULT NULL COMMENT '商品id',
  `number` int(11) DEFAULT NULL COMMENT '数量',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

INSERT INTO `product` VALUES (1, '贵州茅台', 100);

4. SpringBoot 集成 Redisson

4.1 pom.xml

添加redisson-spring-boot-starter包依赖

<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson-spring-boot-starter</artifactId>
    <version>3.16.8</version>
</dependency>

4.2 application.properties

redis相关配置

# redis 相关
spring.redis.host=localhost
spring.redis.port=6379

4.3 buy()

购买商品的方法

  • 判断库存数量是否充足
  • 创建订单
  • 扣减库存数量
@Resource
private RedissonClient redissonClient;

@Override
public Boolean buy(Long productId, Integer number) {
    RLock lock = redissonClient.getLock("lock_key_" + productId);

    try {
        boolean lockRes = lock.tryLock(5, TimeUnit.SECONDS);
        if (!lockRes) {
            throw new RuntimeException("获取锁失败~");
        }

        Product product = productService.getById(productId);
        log.info("库存数量:{}", product.getNumber());
        // ①判断库存是否充足
        if (product.getNumber() < number) {
            throw new RuntimeException("库存不足");
        }

        // ②创建订单
        ProductOrder order = new ProductOrder();
        order.setProductId(productId);
        order.setNumber(1);
        order.setCreateTime(LocalDateTime.now());
        save(order);
        log.info("创建订单:{}", order);

        // ③减库存
        product.setNumber(product.getNumber() - 1);
        productService.updateById(product);
        log.info("减库存:{}", product);
    } catch (InterruptedException e) {
        throw new RuntimeException("出现异常啦~");
    } finally {
        // 释放锁
        lock.unlock();
    }

    return true;
}
  • "lock_key_" + productId这里对商品id加锁,同时只能有一个请求线程操作这个商品,其它请求线程必须等待。
  • 对商品id加锁表明每一种商品都是独立加锁的,就相当于你上厕所的时候是把那个坑位的门给关了,而不是把卫生间的门给关了。
  • lock.tryLock(5, TimeUnit.SECONDS),这里设置加锁的时间为5秒,如果当前请求线程5秒内还没有执行完操作就自动释放锁,让下一个线程来进行操作。

4.4 加锁与不加锁分析

不加锁会出现什么问题?

假设库存还剩最后1瓶茅台,用户A和用户B同时发起购买1瓶茅台请求,用户A的请求线程判断库存充足,但还没有执行完创建订单和减库存操作(操作需要访问数据库,比较耗时)。此时用户B的请求线程判断库存数量为1,库存也充足,也进入了创建订单和减库存操作,最后创建了两个订单,库存减了两次。

我们对商品加锁后,当用户A的请求线程执行判断库存、创建订单、减库存的购买操作过程中,用户B的请求线程需要等待用户A把这一系列操作做完释放了锁之后才能去执行。

5. 测试

接口地址:http://localhost:8100/product/buy

用JMeter创建10个线程模拟多用户同时循环请求接口,当不加锁的情况下,如下是真实测试的结果:100瓶茅台产生了204个订单。

当加锁后,100瓶茅台正常产生100个订单。

JMeter的使用可以看前面Sentinel 流量控制和接口防护那一篇文章。

6. 结语

这里通过简单的抢购茅台的例子来演示锁,Redisson分布式锁可以用于单体或者微服务,它是借助redis中间件来加锁,如上内容我们可以创建多个微服务实例,然后调用接口结果也是一样的。

记住:在限时抢购活动中,大量用户通过网络同时请求购买同一个商品,可能导致系统出现并发抢购的情况,从而会导致商品售罄或者超卖等问题。这种情况下一定要用锁,不管是单体应用还是微服务。


Spring Cloud 微服务系列 完整的代码在仓库的sourcecode/spring-cloud-demo目录下。

gitee(推荐):https://gitee.com/cunzaizhe/xiaohuge-blog

github:https://github.com/tigerleeli/xiaohuge-blog

关注微信公众号:“小虎哥的技术博客”,让我们一起成为更优秀的程序员❤️!

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

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

相关文章

破信息壁垒,亿发一站式ERP系统建设,打造五金制造信息管理平台

五金制造拥有明显的行业特征&#xff0c;如体量小、品种繁多、颜色多样、加工工艺不断演进等&#xff0c;呈现出一种独特的管理挑战。大多数五金企业仍然依赖人工管理和经验决策&#xff0c;如今需要寻求更合理和科学的决策方法&#xff0c;以实现生产、销售、仓储、采购和财务…

无人机如何做到自动巡检?关键技术步骤分析

无人机应用在电网、水利、交通、城管等巡逻巡检领域带来了巡视效率的提升。同时飞手操作的难度和门槛、野外环境的影响、巡检结果处理难度大等带来一系列的巡检问题&#xff0c;自动化的无人机巡检则能很好的解决这些问题&#xff0c;比如我们比较熟知的自动机场&#xff0c;它…

【DETR】

https://tianfeng.space/ 前言 论文 代码 DETR&#xff08;Data-efficient Image Transformer&#xff09;是一种用于目标检测任务的深度学习模型。它与传统的目标检测方法不同&#xff0c;采用了Transformer架构&#xff0c;将目标检测问题转化为一个序列到序列的问题。以下…

【广州华锐互动】VR消防队灭火实训:让消防安全教育变得更生动有趣!

VR消防队灭火实训是一种基于虚拟现实技术的消防培训及模拟&#xff0c;学习如何在火灾中保护自己的自救和逃生方法、技能。这种平台可以让市民在虚拟环境中进行火灾逃生训练&#xff0c;提高人的消防意识和自救能力。 传统的消防培训方式通常是通过理论讲解和现场演示来进行&am…

《论文阅读27》SuperGlue: Learning Feature Matching with Graph Neural Networks

一、论文 研究领域&#xff1a; 图像特征点匹配论文&#xff1a;SuperGlue: Learning Feature Matching with Graph Neural NetworksCVPR 2020veido论文code 二、论文简述 [参考] [参考] [参考] 三、论文详述 SuperGlue&#xff1a;使用图神经网络学习特征匹配 本文介绍了…

【AI视野·今日Sound 声学论文速览 第十一期】Mon, 25 Sep 2023

AI视野今日CS.Sound 声学论文速览 Mon, 25 Sep 2023 Totally 1 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Sound Papers Deepfake audio as a data augmentation technique for training automatic speech to text transcription models Authors Alexandre R. …

Hashable/哈希协议, Arrays/数组 的使用

1. Hashable 模型实现哈希协议 1.1 实现 /// Identifiable struct MyCustomModel: Hashable{//let id UUID().uuidStringlet title: Stringfunc hash(into hasher: inout Hasher) {hasher.combine(title)} }/// 哈希协议: 唯一标识值 struct HashableBootcamp: View {// 每个…

山西电力市场日前价格预测【2023-09-27】

日前价格预测 预测说明&#xff1a; 如上图所示&#xff0c;预测明日&#xff08;2023-09-27&#xff09;山西电力市场全天平均日前电价为342.48元/MWh。其中&#xff0c;最高日前电价为454.24元/MWh&#xff0c;预计出现在18: 30。最低日前电价为171.32元/MWh&#xff0c;预计…

2023 年度编程语言榜单排名揭晓,Python稳坐多项第一

随着科技的迅速发展&#xff0c;编程语言已成为现代社会不可或缺的一部分&#xff1a; 无论是网站开发、移动应用、人工智能还是嵌入式系统&#xff0c;编程语言都扮演着关键角色。 当下流行的AI人工智能大多是通过Python语言实现的。 作为AI技术框架的基础语言&#xff0c;…

华为OD机试 - 工号不够用了怎么办 - 双指针(Java 2023 B卷 100分)

目录 专栏导读一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;A卷B卷&#…

[CSCCTF 2019 Qual]FlaskLight 过滤 url_for globals 绕过globals过滤

目录 subprocess.Popen FILE warnings.catch_warnings site._Printer 这题很明显就是 SSTI了 源代码 我们试试看 {{7*7}} 然后我们就开始吧 原本我的想法是直接{{url_for.__globals__}} 但是回显是直接500 猜测过滤 我们正常来吧 {{"".__class__}} 查看当前…

项目经理如何顺利推进项目:做好任务规划,合理安排时间

在一个项目中&#xff0c;项目经理经常需面对超负荷的工作&#xff0c;并需要通过加班来达成每日的工作任务&#xff0c;他们时常需处理各种任务和大量的电子邮件。这导致项目经理在项目实施过程中&#xff0c;经常处于“救火”状态&#xff0c;而无法有效管理项目进程&#xf…

性能测试分类

一. 基准测试 二. 负载测试 通过逐步增加系统负载&#xff0c;测试系统性能的变化&#xff0c;在满足性能指标的前提下&#xff0c;系统所能承受的最大负载量的测试。 健身&#xff1a;举哑铃 10斤哑铃&#xff0c;举起10个需要15s 20斤哑铃&#xff0c;举起10个需要15s 30斤…

上海亚商投顾:沪指缩量调整 新型工业化板块掀涨停潮

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一.市场情绪 沪指昨日缩量震荡调整&#xff0c;创业板指再度跌破2000点关口。新型工业化板块掀涨停潮&#xff0c;华辰装备…

SourceTree 账号或者密码输入错误 Incorrect username or password ( access token )解决办法

修改来修改去一直解决不了&#xff0c;那就试试查看一下源文件记录的账号密码吧&#xff01;

聚势共赢!爱创科技喜获“腾讯健康年度优秀合作伙伴”!

2023年9月7日—8日&#xff0c;2023腾讯全球数字生态大会在深圳国际会展中心成功举办。来自行业的重磅院士学者、企业代表、生态伙伴等共赴大会&#xff0c;围绕“智变加速&#xff0c;产业焕新”这一活动主题进行了深层次、全方位的交流和探讨&#xff0c;共话大模型时代下数智…

华为智能企业上网行为管理安全解决方案(2)

本文承接&#xff1a; https://blog.csdn.net/qq_37633855/article/details/133339254?spm1001.2014.3001.5501 重点讲解华为智能企业上网行为管理安全解决方案的部署流程。 华为智能企业上网行为管理安全解决方案&#xff08;2&#xff09; 课程地址方案部署整体流程组网规划…

【云上探索实验室】编程范式变革进行时——CodeWhisperer实践全流程及测评分析报告

目录 一、基于LLM的辅助编程——编程范式变革进行时二、CodeWhisperer VS Code 安装与配置2.1、扩展安装2.2、配置 三、CodeWhisperer实践全流程3.1、CodeWhisperer基础实验3.2、CodeWhisperer项目实践——Web端宝可梦图鉴 四、CodeWhisperer测评分析报告4.1、功能性分析4.2、…

AI赋能的3D资产管理

推荐&#xff1a;用 NSDT编辑器 快速搭建可编程3D场景 想象一下&#xff0c;作为一名视频游戏设计师&#xff0c;你希望在游戏中使用 3D 龙模型。 以前&#xff0c;你可以通过两种方式执行此操作&#xff1a; 自己制作复杂的 3D 模型或从多个角度拍摄龙模型的照片。前往 3D 模…

远程计算机或设备不接受连接解决方法

远程计算机或设备不接受连接解决方法 点击左下角开始&#xff0c;点击运行&#xff0c;输入inetcpl.cpl&#xff0c;点击确定&#xff0c;打开Internet选项。 将三个框的勾勾去掉&#xff0c;即为不选中状态&#xff0c;点击确定。 当你的电脑浏览器不能正常上网时&#xff…