背景

原理

在学习Redis分布式锁时编写Service类,其中包含加锁和解锁两个方法,通过调用Redis的SETNX和GETSET方法加锁
请输入图片描述

请输入图片描述

源码

为便于查看,加了logback进行日志打印
请输入图片描述

请输入图片描述

需要加锁的方法,该方法为模拟抢购场景的实现
请输入图片描述

交由SpringBoot自动注入写好的RedisLock包(其实问题出在这里,本应该是10*1000,手误写成10*000结果为0,故所有超时为0
请输入图片描述

访问Controller,一个为抢购地址,抢购地址访问一次则数量减一,一个为查询地址
请输入图片描述

压测工具

使用Apache AB模拟高并发访问

并发测试

手动测试

手动访问,测试功能是否正常
查询
请输入图片描述

订购
请输入图片描述

压测

10个请求,单线程发起测试
请输入图片描述

数量正常
请输入图片描述

50个请求,2个线程发起测试
请输入图片描述

出错

数量显然不对
请输入图片描述

查看日志,发现后续请求都从判断锁是否过期的方法获得的锁,但执行上数值一致,逻辑也没问题
请输入图片描述

原因

后来发现在高并发情况下超时时间如果设置过小,多个线程可能获得的时间戳一致,导致加锁无效,即每个线程都在判断时间戳时可以获得锁,导致“超售”
请输入图片描述

再次压测

数量正常
请输入图片描述

提高并发量
请输入图片描述

数量正常,问题解决
请输入图片描述

Last modification:September 7th, 2023 at 02:57 pm
如果觉得我的文章对你有用,请随意赞赏