09、SpringCloud -- 利用redis的原子性控制高并发请求访问到service层、本地标识

利用redis的原子性控制请求

利用redis的原子性控制人数请求访问到service层

问题:

在秒杀服务中,如果有1万个请求进入到service层,而我们秒杀的商品库存只有10个,说明只有10个请求会成功,剩余的9990个请求进入到service层是失败的,但是即使失败,这9990个请求也会操作到我们的数据库DB

需求:

需要控制进入到service层的人数,比如我们只放10个请求到service层。

思路

把库存数量放在redis里面,利用redis的原子性操作,因为redis是单线程的,即使项目使用到了集群,多个线程同时去秒杀访问,但是在redis里面,因为是单线程的,所以也是一个一个去减的,减的方法是decr操作。

什么是原子性的操作?

原子性指的是因为redis是单线程的,即使多个集群服务,多线程去访问redis的时候,redis也是一个线程一个线程执行的。这就是redis的原子性。

在这里插入图片描述

代码思路:

1、项目都是有一个后台管理系统进行数据管理的,所以我们可以在进行秒杀操作前进行一个初始化操作,通过去管理系统获取秒杀商品的库存,放到redis里面作为预库存,作为判断条件。

2、然后在controller的秒杀方法里面,通过判断redis是否有有预库存,来判断是否进行后续访问数据库的减库存操作。从而实现控制人数访问到service层。

代码:

1、手动初始化redis里面秒杀商品的预库存—就是把库存查出来set到redis里面去

工具类

把秒杀服务的redis前缀生成工具类
在这里插入图片描述

依赖

在这里插入图片描述

SeckillGoodController

手动初始化库存到redis

在这里插入图片描述

初始化成功

http://localhost:8092/seckillGood/initSeckillData

在这里插入图片描述

SeckillOrderInfoController

秒杀方法加判断

在这里插入图片描述

测试:

测试前数据清空处理:

1、flushdb 删除当前数据库中的所有Key

在这里插入图片描述

2、

清除t_user 表数据、

清除D盘的 token.txt 内容,

清空t_order_info 和 t_seckill_order 表。

t_seckill_goods 的 stock_count 改成10

在这里插入图片描述

结果:

在这里插入图片描述
注意事项:

通过几次测试,正常压测数据就符合期望,如果在压测的时候进行debug,打个断点,那么会导致数据不正确,就是秒杀成功的数量小于10,就是10个秒杀商品没有全部被秒杀成功。

如果不打断点,就一切正常。

本地标识的分析和实现

问题:

有一万个请求,上面的超卖跟重复下单,通过redis,最终只让10个请求访问到service层,访问到数据库,那么数据库的压力就小了。但是,虽然redis基于内存访问很快,但是也是有网络开销的。

需求:

一万个秒杀请求访问到redis也是要有网络开销的,但是秒杀商品只有10个,那么处理到访问redis也只有10次的网络开销就可以了。

之前是这样的,1万个请求,都会去访问redis,即使没有库存了,后面的9990个请求也都会去访问redis进行判断

在这里插入图片描述

思路:

定义一个变量作为本地标识,如果redis还有库存,那么就为false,没有库存就为true,当10个库存秒杀完了,那么其他到redis的请求就抛个异常就可以了,就没有必要再去访问redis了。

选用ConcurrentHashMap形式把商品秒杀的id和标识存到redis中。

图片中的ConcurrentHashMap 少写了Con
在这里插入图片描述

代码:

在这里插入图片描述

测试:

测试条件:
在这里插入图片描述
因为debug可能会有些超时,导致数据不准确,用打印的方式来看测试结果,数据库的结果也都是正确的,成功秒杀10个商品,没有重复下单和超卖的问题。

在这里插入图片描述
在这里插入图片描述
测试成功

在这里插入图片描述

这里的失败测试,因为测试线程数是20,这里应该也是10次才对,只要9次,先不理。

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_L_J_H_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值