背景
原理
在学习Redis分布式锁时编写Service类,其中包含加锁和解锁两个方法,通过调用Redis的SETNX和GETSET方法加锁
源码
为便于查看,加了logback进行日志打印
需要加锁的方法,该方法为模拟抢购场景的实现
交由SpringBoot自动注入写好的RedisLock
包(其实问题出在这里,本应该是10*1000
,手误写成10*000
结果为0
,故所有超时为0
)
访问Controller,一个为抢购地址,抢购地址访问一次则数量减一,一个为查询地址
压测工具
使用Apache AB模拟高并发访问
并发测试
手动测试
手动访问,测试功能是否正常
查询
订购
压测
10个请求,单线程发起测试
数量正常
50个请求,2个线程发起测试
出错
数量显然不对
查看日志,发现后续请求都从判断锁是否过期的方法获得的锁,但执行上数值一致,逻辑也没问题
原因
后来发现在高并发情况下超时时间如果设置过小,多个线程可能获得的时间戳一致,导致加锁无效,即每个线程都在判断时间戳时可以获得锁,导致“超售”
再次压测
数量正常
提高并发量
数量正常,问题解决