概述
文章目录
- 参考博客
- 测试工具
- 项目要点
- 1、库存扣除
- 2、接口验证
- 3、接口限流
- 4、缓存一致性
- 5、消息队列处理下单
参考博客
秒杀系统[从零开始的秒杀系统设计]
测试工具
JMeter:用于多线程测试接口。
项目要点
另一种角度分析:
- 高性能:静态资源,CDN
- 一致性:分布式锁,减库存的几种方式
- 高可用:集群,哨兵,流量控制,消息队列
1、库存扣除
未加任务处理的下单请求,极有可能在高并发环境下造成超卖。
即库存减少了100个,订单生成了1000个。
解决方案
使用分布式锁对库存进行处理。
- 1、分布式锁 数据库锁
- 1.1、乐观锁;使用version字段,每次update时判断version是否一致(每个update会持有这个记录的排他锁)
- 1.2、悲观锁;使用FOR UPDATE关键词,每次请求使用@Transactional事务,FOR UPDATE加行锁
- 2、分布式锁 redis锁
- set key value NX PX expire
- 3、Zookeeper
2、接口验证
防止一些人使用脚本对接口进行大量发送。
当秒杀时间到达后才能访问,生成一个hash值,秒杀请求需要带该hash值才有效,否则直接拒绝。
3、接口限流
对秒杀接口进行限流,对用户限流,对接口限流。
计数法:对某一时间接口访问的次数进行统计,然后过一段时间后清空,再次统计。
令牌桶法:桶中存放一定的令牌数量,同时每个时间段生成一批令牌。每个请求消耗一个令牌,当令牌桶为空时拒绝请求。
桶漏法:将请求都放进一个桶中,然后按照指定速率放行。
4、缓存一致性
redis中的缓存和数据库中的数据需要保持一致性。
两种方案:
更新缓存:1000个请求就要更新1000次缓存,效率太低
删除缓存:每次更新库中数据后,删除缓存。先删除缓存,后更新数据库;还是先更新数据库,后删除缓存。
- 先删除缓存:A请求删除缓存,然后准备更新数据库时;B请求获取缓存失效,查询数据库得到旧数据,然后A请求更新数据库;此时缓存为脏数据。
- 先更新数据库:缓存刚好失效,A请求数据,还未写入缓存时;B请求更新数据库,删除缓存;然后A将请求的数据写入缓存;此时缓存为脏数据。
- 延时双删策略:综上可知,无论是先删还是后删,总会有问题,所以这个时候边有了第三种方式。先删除一次缓存,然后执行数据库更新操作,最后一定时间后再删除缓存(将中途可能的脏数据清除)。
5、消息队列处理下单
请求成功之后并不对库存进行处理。而是发送消息到消息队列,订单服务从中获取消息进行下单处理
最后
以上就是迅速招牌为你收集整理的JAVA 秒杀系统总结的全部内容,希望文章能够帮你解决JAVA 秒杀系统总结所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复