百万级并发分布式锁

需求是要支持春节百万并发高并发抢购红包商品。

架构师经过多方技术调研,整理开发以下几个核心步骤:
1.使用redis缓存icon支持高并发
2.商品数据量先存入缓存icon中
3.抢购商品锁定,并从缓存中读取数量减1
4.释放商品锁

代码

import org.redisson.Redisson;

import org.redisson.api.RLock;

import org.redisson.api.RAtomicLong;

import org.redisson.config.Config;

 

public class RedPacketPurchaseService {

 

    private static final Redisson redisson = initRedisson();

    private static final String PRODUCT_ID = "product_id";

    private static final String STOCK_KEY = "stock:" + PRODUCT_ID;

    private static final String LOCK_KEY = "lock:" + PRODUCT_ID;

 

    private static Redisson initRedisson() {

        Config config = new Config();

        config.useSingleServer().setAddress("redis://localhost:6379");

        return Redisson.create(config);

    }

 

    public boolean purchase() {

        RLock lock = redisson.getLock(LOCK_KEY);

        try {

            // 使用公平锁并设置超时时间防止死锁

            if (lock.tryLock(10, TimeUnit.SECONDS)) {

                try {

                    RAtomicLong stock = redisson.getAtomicLong(STOCK_KEY);

 

                    if (stock.decrementAndGet() > 0) {

                        System.out.println("用户成功抢购一个红包商品,剩余库存: " + stock.get());

                        // 这里省略了持久化到数据库的操作,实际应用中需要异步保存购买记录

                        return true;

                    } else {

                        // 库存不足,正常情况下不需要还原库存,这里仅作为演示

                        stock.incrementAndGet();

                    }

                } finally {

                    lock.unlock();

                }

            } else {

                System.out.println("当前抢购人数过多,请稍后再试");

            }

        } catch (InterruptedException e) {

            Thread.currentThread().interrupt();

            System.out.println("线程中断,抢购失败");

        }

 

        return false;

    }

 

    // 在服务启动时或者定时任务中预加载商品库存至Redis Atomic Long

    public void preloadStock(int initialStock) {

        RAtomicLong stock = redisson.getAtomicLong(STOCK_KEY);

        stock.set(initialStock);

    }

}

 

               

**注意事项**:

- 上述代码使用了Redisson提供的`RLock`实现分布式锁,并结合`RAtomicLong`进行原子性的库存扣减,能在一定程度上保证在高并发下的数据一致性。

- 实际生产环境中还需要考虑更多的因素,如网络延迟、服务器性能、数据库写入瓶颈等,并可能需要引入更复杂的策略,例如队列、延时消息队列(如RabbitMQ或RocketMQ)、降级处理等手段来确保系统的稳定性和可用性。

- 另外,为了应对百万级甚至更高的并发,通常还会对系统进行水平扩展,增加服务器数量并通过负载均衡器分配请求,同时也要注意数据库层面的优化和分库分表等操作。

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

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

相关文章

国产制造,欧美品质:爱可声助听器产品质量获国际认可

随着科技的发展和全球化的推进,越来越多的中国制造产品开始走向世界舞台。其中,爱可声助听器凭借其卓越的产品质量,成为了国产制造的骄傲。 国产制造指的是在中国境内生产的产品,欧美品质则是指产品在设计、生产、质量控制等方面…

基于RBF神经网络的自适应控制器simulink建模与仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 4.1自适应控制器 4.2 RBF神经网络模型 5.完整程序 1.程序功能描述 在simulink中,使用S函数编写基于RBF神经网络的自适应控制器,然后实现基于RBF神经网络的自适应控制…

手撕链表OJ

𝙉𝙞𝙘𝙚!!👏🏻‧✧̣̥̇‧✦👏🏻‧✧̣̥̇‧✦ 👏🏻‧✧̣̥̇:Solitary-walk ⸝⋆ ━━━┓ - 个性标签 - :来于“云”的“羽球人”。…

Vue CLI学习笔记

在看任何开源库的源码之前,必须先了解它有哪些功能,这样才能针对性地分模块阅读源码。 Vue CLI 简介 Vue CLI是Vue.js的官方命令行工具,它是一个基于Vue.js进行快速开发的完整系统。 通过Vue CLI,开发者可以快速搭建和开发Vue.js项…

VC++ 绘制折线学习

win32 有三个绘制折线的函数; Polyline,根据给定点数组绘制折线; PolylineTo,除了绘制也更新当前位置; PolyPolyline,绘制多条折线,第一个参数是点数组,第二个参数是一个数组、指…

QT学习事件

一、事件处理过程 众所周知 Qt 是一个基于 C 的框架,主要用来开发带窗口的应用程序(不带窗口的也行,但不是主流)。 我们使用的基于窗口的应用程序都是基于事件,其目的主要是用来实现回调(因为只有这样程序…

Leetcode 392 判断子序列

题意理解: 给定字符串 s 和 t ,判断 s 是否为 t 的子序列。 字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"是"abcde&quo…

WebServer 之 http连接处理(上)

目录 🌼基础知识 epoll HTTP 报文格式 HTTP 状态码 有限状态机 🌙http 处理流程 🐎http 报文处理 🎂http类 🎂请求报文--接收 🐎epoll 相关代码 🧜‍服务器接收 http 请求 &#x1f…

Qt 说明Q_PROPERTY的作用

在Qt框架中,Q_PROPERTY是一种宏,用于声明一个类的属性。Q_PROPERTY宏可以告诉Qt元对象系统(Meta-Object System)关于类的属性信息,比如属性的名称、类型、读写权限、通知信号等。这样可以让Qt的元对象系统能够对类的属性进行动态的查询和操作,比如在运行时动态获取和设置…

HTML快速入门教程

HTML:超文本标记语言(Hyper Text Markup Language),是通过标签的形式将内容组织起来然后共享到网络之上供其他电脑访问查看。 大家可以思考一下,怎么将自己电脑上的文件或图片共享给其他电脑? 这时候会说通…

.target勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复

导言: 网络安全威胁如勒索病毒已经成为企业和个人数据安全的重大挑战之一。.target勒索病毒作为其中的一种,以其高度复杂的加密算法和迅速变化的攻击手法备受关注。本文将深入介绍.target勒索病毒的特点,探讨如何有效地恢复被加密的数据文件…

【小记】MacOS Install golang

问题 - command not found: go ➜ brew install golang ➜ go version go version go1.21.7 darwin/arm64写在最后:若本文章对您有帮助,请点个赞啦 ٩(๑•̀ω•́๑)۶

关闭Windows系统自动更新的方法

关闭Windows系统自动更新的方法在不同版本的Windows中有所不同,以下是一些适用于不同Windows版本的步骤: Windows 10/11 方法一:通过“设置”关闭 打开“设置”(可通过点击开始菜单或使用快捷键Win I)。转到“更新和安…

【Visual Studio】使用空格替换制表符

环境 VS版本:VS2013 问题 如何生成空格替换制表符? 步骤 1、菜单 工具->选项,文本编辑器->C/C->制表符,选择【插入空格】。

[嵌入式系统-18]:RT-Thread -4- shell组件与常见命令

目录 一、RT-Thread shell组件 二、FinSH控制台 三、Shell组件提供了一些常用的命令集 一、RT-Thread shell组件 RT-Thread的Shell组件是一个命令行解析器和执行器,它提供了一个交互性的命令行界面,使用户能够通过输入命令来与嵌入式设备进行交互。 …

电容串联额定耐压问题

例如:两个电容器,其中电容C1 200uF,耐压UM1 100V;电容C2 50uF,耐压UM2500V。 (1)若将两电容串联使用,其等效电容和耐压各是多少? (2)若将两电容器并联使用,其等效电容和耐压各是多少? 分析: (1&…

Ubuntu Desktop - Terminal 输出全部选中 + 复制

Ubuntu Desktop - Terminal 输出全部选中 复制 1. Terminal2. Terminal 最大化3. Edit -> Select All4. Copy & PasteReferences 1. Terminal 2. Terminal 最大化 3. Edit -> Select All 4. Copy & Paste Edit -> Copy or Shift Ctrl C Edit -> Paste…

深度理解实分析:超越公式与算法的学习方法

在数学的学习旅程中,微积分和线性代数为许多学生提供了直观且具体的入门体验。它们通常依赖于明确的公式、算法以及解题步骤,而这些元素往往可以通过记忆和机械练习来掌握。然而,当我们迈入实分析的领域时,我们面临着一种全新的挑…

【蓝桥杯单片机入门记录】认识单片机

目录 单片机硬件平台 单片机的发展过程 单片机开发板 单片机基础知识 电平 数字电路中只有两种电平:高和低 二进制(8421码) 十六进制 二进制数的逻辑运算 “与” “或” “异或” 标准C与C51 如何学好单片机 端正学习的态度、培…

最详细STM32 启动流程

一、STM32三种启动方式 常规模式(主闪存存储器): 这是最常见的启动模式。在此模式下,处理器会执行复位向量表中的复位地址,从而启动芯片。芯片会执行各种初始化操作,包括时钟初始化、外设初始化等&#xff…