情景假设:现在华为最新手机在做活动,双十二 00:00 准时前十名抢购的用户可以1元秒杀。而数据库对这个秒杀的动作呢,需要作出两个动作:
1、库存减1
2、记录秒杀成功的用户id
话不多说,我们直接用代码来演示:
这里直接给出控制器方法。
@PostMapping("/secKill") public void TestSecKill(){ /** * 实际开发,我们需要获取用户的id和商品的id * 这里作为学习使用,我们先写死 */ //用户id,我们使用随机数来表示每次访问的不同用户 String userid = new Random().nextInt(50000) + ""; //商品id,我们先写死 String prodid = "1001"; //1、连接redis(如果有设置requirepass的话,记得添加jedis.auth("你的密码"); Jedis jedis = new Jedis("119.91.153.74", 6379); //2、拼接key String kcKey = "sk:"+prodid+":qt"; //库存key String userKey = "sk:"+userid+":user"; //秒杀成功用户key //使用乐观锁,监视库存 jedis.watch(kcKey); //3、获取库存,为null表示活动未开始 String kc = jedis.get(kcKey); if(kc == null){ System.out.println("秒杀还未开始"); jedis.close(); return; } //4、判断用户是否重复秒杀 if(jedis.sismember(userKey, userid)){ System.out.println("您已成功秒杀,不可重复秒杀"); jedis.close(); return; } //5、库存小于等于0,秒杀结束 if (Integer.parseInt(kc) <= 0){ System.out.println("秒杀活动已结束,感谢您的参与"); jedis.close(); return; } //6、秒杀过程 //开启事务 Transaction transaction = jedis.multi(); //组队 //6.1 库存减1 transaction.decr(kcKey); //6.2 添加秒杀成功用户 transaction.sadd(userKey, userid); //执行 List<Object> results = transaction.exec(); //执行失败 if (results == null || results.size() == 0){ System.out.println("秒杀失败....."); jedis.close(); return; } //执行成功 System.out.println("恭喜您秒杀成功......."); jedis.close(); }
然后我们来测试一下:
首先,先给redis添加库存:
set sk:1001:qt 10
然后我们使用ab工具模拟并发:
这里顺便介绍几个命令:
命令 | 描述 |
---|---|
-n | requests:请求次数 |
-c | concurrency:并发数 |
-T | content-type:用于POST和PUT请求,其值固定为’application/x-www-form-urlencoded’ |
-p | postfile:如果post请求有参数,要放到该文件中 |
-u | putfile:如果put请求有参数,要放到该文件中 |
基本介绍就这么多,接下来我们直接用,使用命令:
注意:即使post请求没有参数,也要使用-p标签,否则好像会默认使用get请求,192.168.148.148是Tomcat服务器的ip地址(这里我的是我的windows的ip地址)。
ab -n 1000 -c 100 -p postfile -T ‘application/x-www-form-urlencoded’ http://192.168.148.148:8080/secKill
如果要查询自己本机的ip地址的话,在cmd下输入 ipconfig即可。它里面有一个Ipv4地址就是你的ip地址啦。
如果Linux服务器访问不了你的windows,那么我们也可以在windows上下载ab工具,并使用python来模拟我们的并发测试。
import os #D:\Download\httpd-2.4.51-o111l-x64-vc15\Apache24\bin\ab是我们的ab工具路径 ab=os.popen(r'D:\Download\httpd-2.4.51-o111l-x64-vc15\Apache24\bin\ab -n 1000 -c 100 -p ./postfile -T application/x-www-form-urlencoded http://192.168.148.148:8080/secKill') print(ab.read())
运行结果:(可以看到秒杀成功的次数是10次,成功解决了我们的超卖问题)
我们再去Redis下查看:
安装命令:
yum install httpd-tools
ab工具官网下载地址:https://www.apachehaus.com/cgi-bin/download.plx
进入后往下拉:
下载完成后直接解压即可。