使用Redis实现分布式锁解决商品超卖问题(接上篇文章)

news2024/12/22 20:29:01

1. RedLock(红锁)简介

在这里插入图片描述

RedLock是一种用于分布式系统的锁定算法,旨在提供分布式锁的高可用性和分布式容错性。它是由Redis的创建者Salvatore Sanfilippo提出的,用于克服Redis单实例的单点故障问题。RedLock的目标是确保在多个Redis实例上获取锁时,锁定操作在大多数实例上都成功。

RedLock的基本思想是,获取分布式锁需要在多个Redis实例上获取锁,至少需要在N/2 + 1个Redis实例上成功获取锁,其中N表示Redis实例的总数。这样做是为了保证锁在大多数实例上是可用的。

RedLock的步骤如下:

  • 获取当前时间戳。

  • 在每个Redis实例上尝试获取锁,使用相同的锁名称、唯一标识符和超时时间。

  • 统计成功获取锁的实例数量。

  • 如果成功获取锁的实例数量大于等于N/2 + 1,则认为锁获取成功。

  • 否则,在成功获取锁的实例上释放锁,确保锁不会被占用。

RedLock的优点是它提供了高可用性,即使其中一个Redis实例出现问题,其他实例仍可以提供服务。然而,需要注意的是,RedLock仍然依赖于Redis,如果所有Redis实例都无法正常工作,那么RedLock也无法正常运行。

总之,RedLock是一种用于提供分布式锁的算法,它充分考虑了高可用性和分布式容错性,适用于需要可靠锁定机制的分布式系统。

2. Redisson简介

Redisson是一个开源的Java框架,它为Redis提供了一组分布式Java对象和服务,使得在Java应用程序中使用Redis变得更加容易。Redisson的目标是简化分布式系统的开发,提供易于使用的API和丰富的功能集合,以满足不同分布式应用的需求。

Redisson提供了一些常见的分布式数据结构和服务,如分布式锁、分布式集合、分布式Map、分布式队列、分布式消息发布/订阅等,这些功能可以方便地在分布式应用中使用。Redisson还提供了一种流畅的API,使开发人员可以更容易地与Redis进行交互,同时还提供了许多性能优化和线程安全的功能。

使用Redisson,开发人员可以更容易地构建分布式系统,从而充分利用Redis的强大功能,提高应用程序的性能和可伸缩性。这个框架已经被广泛用于构建各种分布式应用,如缓存、任务队列、分布式锁和会话管理等。

3. 解决方案

3.1 版本12

使用基于红锁的Redission客户端实现分布式加锁多台Redis实例:

  • 添加Redisson依赖:首先,确保你的项目中引入了Redisson依赖。

  • 初始化Redisson:创建Redisson的客户端并配置多个Redis实例的信息。

Config config = new Config();
config.useClusterServers()
      .addNodeAddress("redis://server1:6379")
      .addNodeAddress("redis://server2:6379")
      .addNodeAddress("redis://server3:6379")
      .addNodeAddress("redis://server4:6379")
      .addNodeAddress("redis://server5:6379");

RedissonClient redisson = Redisson.create(config);

  • 获取锁并执行业务逻辑:
RLock lock = redisson.getLock("order_lock");

try {
    boolean isLocked = lock.tryLock(1, 10, TimeUnit.SECONDS); // 尝试获取锁,等待1秒,锁定10秒
    if (isLocked) {
        String retMessage = "";
        try{
            // 1.查询库存
            String resultFromRedis = stringRedisTemplate.opsForValue().get(key);
            // 判断库存是否足够
            Integer num=resultFromRedis == null?0:Integer.parseInt(resultFromRedis);
            if(num-count > 0){
                stringRedisTemplate.opsForValue().set(key,String.valueOf(--num));
                retMessage = "成功卖出"+count+"件商品"+"服务端口号:"+serverPort;
                System.out.println(retMessage+"当前商品剩余:"+(num+1-count)+"件。");
                // 模拟长业务
                try {TimeUnit.SECONDS.sleep(200);} catch (InterruptedException e) {e.printStackTrace();}

            }else{
                retMessage="商品已售罄!非常抱歉!";
                System.err.println(retMessage);
            }
        }
    } else {
        // 获取锁失败,可以处理一些逻辑,如返回错误信息
    }
} finally {
    lock.unlock();
}

  • 关闭Redisson客户端:在应用程序关闭时,记得关闭Redisson客户端。
redisson.shutdown();

这个示例中,我们使用了Redisson的RLock来获取分布式锁,确保只有一个线程能够执行扣减库存的逻辑。如果你的应用需要高可用性和分布式容错性,你可以使用RedLock算法,它需要至少在N/2 + 1个Redis实例上获取锁,以保证锁的可用性。

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

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

相关文章

【LeetCode】144. 二叉树的前序遍历 [ 根结点 左子树 右子树 ]

题目链接 文章目录 Python3方法一: 递归 ⟮ O ( n ) ⟯ \lgroup O(n) \rgroup ⟮O(n)⟯方法二: 迭代 ⟮ O ( n ) ⟯ \lgroup O(n) \rgroup ⟮O(n)⟯方法三: Morris ⟮ O ( n ) 、 O ( 1 ) ⟯ \lgroup O(n)、O(1) \rgroup ⟮O(n)、O(1)⟯ C…

【LeetCode】94. 二叉树的中序遍历 [ 左子树 根结点 右子树 ]

题目链接 文章目录 Python3方法一: 递归 ⟮ O ( n ) ⟯ \lgroup O(n) \rgroup ⟮O(n)⟯方法二: 迭代 ⟮ O ( n ) ⟯ \lgroup O(n) \rgroup ⟮O(n)⟯方法三: Morris ⟮ O ( n ) 、 O ( 1 ) ⟯ \lgroup O(n)、O(1) \rgroup ⟮O(n)、O(1)⟯ C…

【2023年11月第四版教材】软考高项极限冲刺篇笔记(1)

1 你要接受一些观点 1、不明白的不要去试图理解了,死记硬背 2、要快速过知识点,卡住是不行的,慢也是没有任何作用的。 3、将厚厚的知识,变为薄薄的重点。标红必背 4、成熟度等级,很多知识领域都有,就是评价在一个领域达到的级别。 5、记得搜一下当年的高频科技词汇 6、选…

基于tikz package 衰变纲图的LaTeX绘制

衰变纲图的LaTeX绘制 箭头向右:衰变箭头向左: 打开Mathcha 微操导出代码结束全文完

Unity之ShaderGraph如何实现触电电流效果

前言 之前使用ASE做过一个电流效果的shader,今天我们通过ShaderGraph来实现一个电流效果。 效果如下: 关键节点 Simple Noise:根据输入UV生成简单噪声或Value噪声。生成的噪声的大小由输入Scale控制。 Power:返回输入A的结果…

Nginx的基本介绍 安装 配置文件 日志

一、Nginx介绍二、nginx的优点三、多路复用1、I/O multiplexing 多并发 四、nginx内部技术架构五、安装NginxNginx部署-yum安装获取Nginx的yum源yum安装Nginx浏览器访问 编译安装Nginx安装编译环境安装依赖环境创建nginx用户安装nginx启动nginx实现nginx开机自启(脚…

【软考】11.2 开发方法/产品线/软件复用/逆向工程

《信息系统开发方法》 结构化方法(生命周期法) 自顶向下、逐步求精和模块化设计遵循“用户第一”原则 三部分有机组合: a. 结构化分析(SA) b. 结构化设计(SD) c. 结构化程序设计(SP…

微信小程序设计之主体文件app-json-window

一、新建一个项目 首先,下载微信小程序开发工具,具体下载方式可以参考文章《微信小程序开发者工具下载》。 然后,注册小程序账号,具体注册方法,可以参考文章《微信小程序个人账号申请和配置详细教程》。 在得到了测…

Kotlin函数作为参数指向不同逻辑(二)

Kotlin函数作为参数指向不同逻辑(二) fun sum(): (Int, Int) -> Int {return { a, b -> (a b) } }fun multiplication(): (Int, Int) -> Int {return { a, b -> (a * b) } }fun math(a: Int, b: Int, foo: (Int, Int) -> Int): Int {ret…

istio介绍(二)

5. kubesphere istio使用 5.1 整体架构 ks-account 提供用户、权限管理相关的 APIks-apiserver 整个集群管理的 API 接口和集群内部各个模块之间通信的枢纽,以及集群安全控制ks-apigateway 负责处理服务请求和处理 API 调用过程中的所有任务ks-console 提供 KubeSp…

C++之struct匿名结构体实例(二百四十四)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生…

一篇文章掌握C++操作Access数据库

一、可视化工具 我们都知道oracle数据库的可视化工具有:PLSQL Developer、navicat(支持包括oracle的大部分数据库)等,Access数据库的可视化工具是:Microsoft Access,我们安装好微软的office就会自带Micros…

YOLOv5:修改backbone为SPD-Conv

YOLOv5:修改backbone为SPD-Conv 前言前提条件相关介绍SPD-ConvYOLOv5修改backbone为SPD-Conv修改common.py修改yolo.py修改yolov5.yaml配置 参考 前言 记录在YOLOv5修改backbone操作,方便自己查阅。由于本人水平有限,难免出现错漏&#xff0c…

【linux】查看下载应用在服务器的日志

查看日志路径 一般在配置文件中logback.xml 账号密码xshell连接服务器,进入日志路径 根据搜索关键字查看xxx.log文件内容 cat xxx.log | grep 关键字 下载 xxx.log 到本地,一般可以下载当天的日志文件到本地查看比较方便 sz xxx.log 参考文章&#xff…

【数字IC设计/FPGA】FIFO与流控机制

流控,简单来说就是控制数据流停止发送。常见的流控机制分为带内流控和带外流控。 FIFO的流水反压机制 一般来说,每一个fifo都有一个将满阈值afull_value(almost full)。当fifo内的数据量达到或超过afull_value时,将满…

【Leetcode】【中等】260. 只出现一次的数字 III

给你一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。你可以按 任意顺序 返回答案。 你必须设计并实现线性时间复杂度的算法且仅使用常量额外空间来解决此问题。 示例 1: 输入&…

904. 水果成篮(滑动窗口)

目录 一、题目 二、代码 一、题目 力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 二、代码 题目实质:找出一个最长的子数组的长度,要求子数组中不超过两种类型的水果哈希表双指针 class Solution { public:int totalFru…

【XOR秘钥破解】异或加密秘钥破解

1、代码 # -*- coding:utf-8 -*- import binasciioriginal_text input("请输入XOR加密前(字 符 串):") encrypted_text input("请输入XOR加密后(十六进制):")# 先将original_text文…

P1004 [NOIP2000 提高组] 方格取数

[NOIP2000 提高组] 方格取数 - 洛谷 用四维dp数组存储&#xff0c;如果两个路线走到重复点&#xff0c;减去一个当前位置的值即可。 #include <bits/stdc.h> using namespace std; const int N 11; int grid[N][N] {0}; int dp[N][N][N][N] {0}; int n, i, j, tmp; v…

中级职称评审为什么要找机构?甘建二给你分析

职称申报为什么要找机构代理呢&#xff1f;主要是机构可以帮助整理业绩和各种申报材料&#xff0c;而且还可以帮忙网上申报。让您不会错过申报时间什么的&#xff0c;平时个人都是上班太忙了&#xff0c;没有空准备申报材料之类的各种&#xff0c;而且随时掌握申报信息&#xf…