实战!用Redis来实现分布式锁,真香
mhr18 2024-10-27 10:53 31 浏览 0 评论
基于 Redis 的分布式锁对大家来说并不陌生,常见的场景就是电商项目啦,比如秒杀,抢优惠劵等等,一个误操作,就会导致用户重复下单,深圳的一家企业因为这一失误,日损数万元。
本文详细介绍如何利用SoFlu全自动开发平台来实现基于 Redis 的分布式锁,高效又实用,确保系统的安全性以及正确性。
01
实例介绍
为了对某一个共享变量进行多线程同步访问,同时保证该共享变量在高并发情况下的同一时间只能被一个线程执行,我们经常需要用到分布式锁。
本实例将模拟多用户下单减少商品库存数量的场景为您介绍如何使用全自动开发平台实现分布式锁功能,常见的还有电商平台商品秒杀、抢优惠券等。
由于Redis具有性能高、使用方便等功能特点,较为适用于分布式锁功能,故本实例基于Redis上实现。
02
效果展示
说明:本实例使用全自动测试平台进行测试,全自动测试平台是我司自主开发的全自动软件工程平台中第二个实用的平台,覆盖了整个软件测试的生命周期管理,包含测试用例管理、测试计划管理、接口测试、性能测试等功能,可以一键关联和同步全自动开发平台的项目和项目中所有的接口信息。
本实例设置的商品初始化库存数量为10,调用初始化库存接口后,在全自动测试平台进行性能测试,设置了12个并发用户同时发送下单请求(即调用分布式锁接口),此时性能测试报告显示12个请求中,10个请求输出“调用成功”,2个请求输出“库存不足”,如图2-1所示。
图2-1 全自动测试平台测试报告页面
03
流程图设计概览
3.1 初始化库存接口
图3-1 初始化库存接口流程图
逻辑描述:
(1)在Redis缓存上储存初始化库存量,并设置初始化库存量为10;
(2)获取Redis缓存上储存的初始化库存量;
(3)输出Redis缓存上储存的初始化库存量。
3.2 分布式锁接口
图3-2 分布式锁接口流程图
逻辑描述:
(1)构建分布式锁Map集合;
(2)上锁,设置超时释放时间;
(3)获取Redis缓存上存储的当前库存量;
(4)判断当前库存量是否小于等于0,若小于等于0,说明库存量不足,则输出库存不足;若大于0,说明库存量充足,则继续以下流程;
(5)将当前库存量减1,并更新Redis缓存上存储的库存量;
(6)再次获取更新后Redis缓存上的库存量;
(7)输出现存库存量。
04
全自动开发平台具体操作过程
4.1 创建Redis缓存资源实例
前提条件:您需要确保项目中已添加Redis缓存加载项。
进入全自动开发平台“资源实例”功能模块,选择“Redis缓存”,新增Redis缓存资源实例,根据实际情况进行配置,如图4-1所示。
图4-1 Redis缓存资源实例配置图
4.2 创建初始化库存接口
4.2.1.进入全自动开发平台“接口管理”功能模块,新增接口模块并新增初始化库存接口,填写接口的基本信息。
图4-2接口模型功能模块
4.2.2.单击“下一步”,进入配置入口参数页面,该接口不需要配置参数信息。
4.2.3.单击“提交”提交接口信息,进入模型编辑。
图4-4 模型编辑
4.2.4.在窗体视图页面,通过拖拽左侧组件列表中所需的组件进行流程图编辑。
图4-5窗体视图页面
4.3 初始化库存接口中组件的详细配置
4.3.1.在Redis缓存上储存初始化库存量,并设置初始化库存量为10。
使用Redis组件调用Redis方法putBucket(String name, Object value)新增通用对象,用于表示初始化的库存量,传入通用对象名stock以及通用对象参数值10即可。
说明:此处用到的Redis方法类型为Bucket,专门用于操作通用对象,方法说明见下表格。
表4-1 putBucket方法说明
图4-6 Redis组件
【初始化库存数量10】
图4-7 组件配置
4.3.2.使用Redis组件调用Redis方法getBucket(String name)获取Redis缓存上储存的初始化库存量,传入通用对象名stock即可。
图4-8 Redis缓存组件
【获取初始化库存量】
图4-9 组件配置
4.3.3.使用输出结果组件输出Redis缓存上储存的初始化库存量,传入Redis组件【获取初始化库存量】的执行结果即可。
图4-10 输出结果
【输出初始化库存量】
图4-11 组件配置
4.4 测试初始化库存接口
4.4.1.流程图设计完成后,保存并退出窗体视图。
图4-12
4.4.2.提交并发布接口。
图4-13
4.4.3.对接口进行测试用例,检验接口实现的功能是否可以达到预期。
图4-14
4.4.4.执行测试用例。
图4-15
4.4.5.通过测试用例响应内容查看接口的执行结果,data返回10说明此时Redis缓存上储存的库存数量为10。
图4-16
4.5 创建分布式锁接口
4.5.1.新增分布式锁接口,填写接口的基本信息。
图4-17
4.5.2.与初始化库存接口类似,分布式锁接口也不需要配置接口参数,直接进入窗体视图拖拽组件列表中的组件进行流程图的编辑,如下图所示。
图4-18
4.6 分布式锁接口中组件的详细配置
4.6.1.使用单函数组件调用函数newMapInit(Object[] keyAndValue)构建分布式锁Map集合,需传入分布式锁参数名lockKey以及分布式锁参数值product_001。
图4-19 单函数组件
【构建分布式锁名】
4.6.2.使用Redis组件中调用Redis方法lock(String lockName, long leaseTime, TimeUnit unit)用于上锁并设置超时释放时间,需传入上一步构建的分布式锁Map集合,即单函数组件【构建分布式锁名】的执行结果,以及超时时间数和时间单位,本实例设置的超时释放时间为2秒,如图4-27所示。
说明:此处使用的Redis方法类型为Lock,专门用于操作锁,方法说明见下表格。
表4-2 lock方法说明
图4-21 Redis组件
【上锁,超时释放】
图4-22 组件配置
4.6.3.使用Redis组件调用Redis方法getBucket(String name)获取Redis缓存上存储的当前库存量,传入初始化库存接口中创建的通用对象stock即可。
图4-23 Redis缓存组件
【获取当前库存量】
图4-24 组件配置
4.6.4.使用互斥条件组件判断上一步【获取当前库存量】是否小于等于0,若小于等于0,说明库存量不足,则输出库存不足结束流程;若大于0,说明库存量充足,则继续以下流程。
图4-25 【是否有库存】流程
图4-26 小于等于0时流转条件
图4-27 输出结果组件【库存不足】
图4-28 输出库存不足信息
图4-29 大于0时流转条件
4.6.5.使用Redis组件调用Redis方法putBucket(String name, Object value) 将当前库存量减1,并更新Redis缓存上存储的库存量,需传入通用对象名stock以及步骤3中Redis组件【获取当前库存量】的执行结果减1,如图4-31所示。
图4-30 Redis组件
【更新库存量】
图4-31 组件配置
4.6.6.使用Redis组件调用Redis方法getBucket(String name)获取更新后的库存量,传入在Redis缓存上储存的库存量值stock即可。
图4-32 Redis组件
【获取当前库存量】
图4-33 组件配置
4.6.7.使用输出结果组件输出更新后的库存量,传入上一步Redis组件【获取当前库存量】的执行结果即可,如图4-35所示。
图4-34 输出结果
【输出现存库存量】
图4-35 输出提示信息
4.7 测试分布式锁接口
4.7.1.与创建初始化库存接口类似,保存分布式锁接口流程图,退出窗体视图
4.7.2.提交并发布分布式锁接口
4.7.3.对接口进行测试用例,检验接口实现的功能是否可以达到预期。
4.7.4.编辑测试用例。
图4-36
4.7.5.启用可视化日志(便于查看接口流程中的数据流转),单击执行即可。
图4-37
4.7.6.通过测试用例详情页面的响应内容查看接口的执行结果,若当前库存充足时,返回调用成功以及当前库存数量,如图4-38所示;若当前库存不足,返回库存不足输出结果,如图4-39所示。
图4-38 调用成功返回结果
图4-39 库存不足返回结果
4.7.7.若测试用例的结果出现错误,可通过可视化日志双击查看各个组件的节点数据进行接口的调试。
图4-40 选择可视化日志
图4-41 查看可视化日志
图4-42 查看节点数据
05
全自动开发平台具体操作过程
说明:在确保初始化库存接口和分布式锁接口都可以成功执行后,接下来我们使用全自动测试平台进行并发测试。
5.1 前提条件
使用全自动测试平台进行并发测试之前,您需要做好以下相关配置操作:
5.1.1.做好环境配置。
5.1.2.根据实际情况部署所需资源池并新增对应的资源。
说明:具体操作可以前往飞算云智官网文档中心查看全自动测试平台“1-1资源池配置”和“2-2环境配置”部分。
5.2 关联全自动开发平台的项目和接口
5.2.1.单击全自动测试平台页面上方“测试场景 > 接口管理”选项,选择“关联项目”。
图4-43
5.2.2.查询所需关联项目,单击“关联”即可。
说明:本实例使用到的项目名称为test2,您在操作时需根据实际需求选择关联。
图4-44
5.2.3.关联成功后,您可以看到对应项目及所有的接口信息显示在接口管理页面。
图4-45
5.2.4.进入初始化库存接口详情页面,选择好环境配置后,单击“测试”即可调用该接口执行初始化库存操作。
说明:对初始化库存接口进行测试后,最好单击一下保存,以免下次执行时需重新选择,您也可以在全自动测试平台对该接口执行测试用例以初始化库存。
图4-46
5.3 创建分布式锁测试用例
5.3.1.新增测试用例模块。
图4-47
5.3.2.在对应的测试用例模块下,新增测试用例。
图4-48
5.3.3.填写测试用例详细信息。
图4-49
5.3.4.提交测试用例。
图4-50
5.3.5.评审测试用例。
图4-51
5.3.6.评审通过后,单击“提交”即可。
图4-52
5.4 新增分布式锁测试场景
5.4.1.新增测试场景,填写基本信息。
图4-53
图4-54
5.4.2.在根测试场景下创建场景组。
图4-55
5.4.3.为场景组绑定接口。
图4-56
5.4.4.选择“分布式锁”接口。
图4-57
5.4.5.设置断言。
说明:断言用于设置条件对接口返回的数据进行检查,看是否可以通过设置的条件。断言因接口返回数据类型的不同也分为不同的类型,此处选择的是JSON断言,用于判断分布式锁接口返回的msg字段是否为“调用成功!”。若为“调用成功!”,则说明库存充足,用户请求成功,否则说明库存不足,用户请求失败。
图4-58
图4-59
5.4.6.单击“保存”,保存测试场景。
说明:您可以通过执行测试场景检验所设置场景组的是否符合预期效果,但需注意每执行一次,将消耗一次库存。
5.5 进行并发性能测试
5.5.1.进入性能测试页面,创建性能测试。
图4-60
5.5.2.填写性能测试基本信息,选择可用的环境和资源池,导入测试用例。
图4-61
5.5.3.选择创建的分布式锁测试用例,可以看到该测试用例绑定了分布式锁测试场景。
图4-62
5.5.4.设置并发用户数,并选择按持续时间或循环次数进行测试。
说明:因为本实例设置的初始化库存数量为10,此处我们设置12个并发用户数来展示分布式锁效果,同时设置这12个并发用户分别只执行一次分布式锁测试场景(即循环次数为1次),且这12个并发用户需要在1秒内全部生成(即在1秒内增加并发用户)。
图4-63
5.5.5.创建性能测试完成后,单击“保存”。
5.5.6.执行性能测试。
图4-64
5.5.7.稍等片刻后,查看测试报告。
5.6 查看分布式锁性能测试报告
5.6.1.选择测试报告。
图4-65
5.6.2.单击“详情”。
图4-66
5.6.3.查看测试报告详情,报告详情包含压力配置、测试概览、请求统计、错误记录以及监控详情5个部分的数据信息,我们可以在错误记录部分看到此次并发测试发送了12次请求,其中有两次请求因库存不足请求失败。
图4-67
平台现已开启免费试用,地址:https://feisuanyz.com/
相关推荐
- 如何检查 Linux 服务器是物理服务器还是虚拟服务器?
-
在企业级运维、故障排查和性能调优过程中,准确了解服务器的运行环境至关重要。无论是物理机还是虚拟机,都存在各自的优势与限制。在很多场景下,尤其是当你继承一台服务器而不清楚底层硬件细节时,如何快速辨识它是...
- 第四节 Windows 系统 Docker 安装全指南
-
一、Docker在Windows上的运行原理(一)架构限制说明Docker本质上依赖Linux内核特性(如Namespaces、Cgroups等),因此在Windows系统上无法直...
- C++ std:shared_ptr自定义allocator引入内存池
-
当C++项目里做了大量的动态内存分配与释放,可能会导致内存碎片,使系统性能降低。当动态内存分配的开销变得不容忽视时,一种解决办法是一次从操作系统分配一块大的静态内存作为内存池进行手动管理,堆对象内存分...
- Activiti 8.0.0 发布,业务流程管理与工作流系统
-
Activiti8.0.0现已发布。Activiti是一个业务流程管理(BPM)和工作流系统,适用于开发人员和系统管理员。其核心是超快速、稳定的BPMN2流程引擎。Activiti可以...
- MyBatis动态SQL的5种高级玩法,90%的人只用过3种
-
MyBatis动态SQL在日常开发中频繁使用,但大多数开发者仅掌握基础标签。本文将介绍五种高阶技巧,助你解锁更灵活的SQL控制能力。一、智能修剪(Trim标签)应用场景:动态处理字段更新,替代<...
- Springboot数据访问(整合Mybatis Plus)
-
Springboot整合MybatisPlus1、创建数据表2、引入maven依赖mybatis-plus-boot-starter主要引入这个依赖,其他相关的依赖在这里就不写了。3、项目结构目录h...
- 盘点金州勇士在奥克兰13年的13大球星 满满的全是...
-
见证了两个月前勇士与猛龙那个史诗般的系列赛后,甲骨文球馆正式成为了历史。那个大大的红色标志被一个字母一个字母地移除,在周四,一切都成为了过去式。然而这座,别名为“Roaracle”(译注:Roar怒吼...
- Mybatis入门看这一篇就够了(mybatis快速入门)
-
什么是MyBatisMyBatis本是apache的一个开源项目iBatis,2010年这个项目由apachesoftwarefoundation迁移到了googlecode,并且改名为M...
- Springboot数据访问(整合druid数据源)
-
Springboot整合druid数据源基本概念SpringBoot默认的数据源是:2.0之前:org.apache.tomcat.jdbc.pool.DataSource2.0及之后:com.z...
- Linux 中的 "/etc/profile.d" 目录有什么作用 ?
-
什么是/etc/profile.d/目录?/etc/profile.d/目录是Linux系统不可或缺的一部分保留配置脚本。它与/etc/profile文件相关联,这是一个启动脚本,该脚...
- 企业数据库安全管理规范(企业数据库安全管理规范最新版)
-
1.目的为规范数据库系统安全使用活动,降低因使用不当而带来的安全风险,保障数据库系统及相关应用系统的安全,特制定本数据库安全管理规范。2.适用范围本规范中所定义的数据管理内容,特指存放在信息系统数据库...
- Oracle 伪列!这些隐藏用法你都知道吗?
-
在Oracle数据库中,有几位特殊的“成员”——伪列,它们虽然不是表中真实存在的物理列,但却能在数据查询、处理过程中发挥出意想不到的强大作用。今天给大家分享Oracle伪列的使用技巧,无论...
- Oracle 高效处理数据的隐藏神器:临时表妙用
-
各位数据库搬砖人,在Oracle的代码世界里闯荡,处理复杂业务时,是不是总被数据“搅得头大”?今天给大家安利一个超实用的隐藏神器——临时表!当你需要临时存储中间计算结果,又不想污染正式数据表...
- Oracle 数据库查询:多表查询(oracle多表关联查询)
-
一、多表查询基础1.JOIN操作-INNERJOIN:返回两个表中满足连接条件的匹配行,不保留未匹配数据。SELECTa.emp_id,b.dept_nameFROMempl...
- 一文掌握怎么利用Shell+Python实现多数据源的异地备份程序
-
简介:在信息化时代,数据安全和业务连续性已成为企业和个人用户关注的焦点。无论是网站数据、数据库、日志文件,还是用户上传的文档、图片等,数据一旦丢失,损失难以估量。尤其是当数据分布在多个不同的目录、服务...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- 如何检查 Linux 服务器是物理服务器还是虚拟服务器?
- 第四节 Windows 系统 Docker 安装全指南
- C++ std:shared_ptr自定义allocator引入内存池
- Activiti 8.0.0 发布,业务流程管理与工作流系统
- MyBatis动态SQL的5种高级玩法,90%的人只用过3种
- Springboot数据访问(整合Mybatis Plus)
- 盘点金州勇士在奥克兰13年的13大球星 满满的全是...
- Mybatis入门看这一篇就够了(mybatis快速入门)
- Springboot数据访问(整合druid数据源)
- Linux 中的 "/etc/profile.d" 目录有什么作用 ?
- 标签列表
-
- oracle位图索引 (74)
- oracle基目录 (50)
- oracle批量插入数据 (65)
- oracle事务隔离级别 (53)
- oracle主从同步 (55)
- oracle 乐观锁 (51)
- redis 命令 (78)
- php redis (88)
- redis 存储 (66)
- redis 锁 (69)
- 启动 redis (66)
- redis 时间 (56)
- redis 删除 (67)
- redis内存 (57)
- redis并发 (52)
- redis 主从 (69)
- redis 订阅 (51)
- redis 登录 (54)
- redis 面试 (58)
- 阿里 redis (59)
- redis 搭建 (53)
- redis的缓存 (55)
- lua redis (58)
- redis 连接池 (61)
- redis 限流 (51)