JAVA项目笔记--黑马店铺的优惠卷秒杀

news/2025/2/23 0:35:44/文章来源:https://www.cnblogs.com/tdsmomo/p/18728060

功能实现介绍:
先判断优惠卷的信息保证不过期等,为了防止一个用户多次进行插入,要结合悲观锁。故
根据userId在redis生成分布式锁,使得之后的用户请求无法实现。
生成订单。是对优惠卷的数目进行更新,可以使用乐观锁,所以在插入前,判断某个值是否满足即库存是否大于0,如果大于则继续执行,

可能出现的问题(线程安全):
1.单用户多购买:
在线程a执行插入操作时,线程b绕过了当前无订单的判断也准备执行插入操作。

2.在多用户准备进行消费卷抢购时,密集执行库存减操作导致库存出现负数。

全局id生成

alt text
生成原因:使用自增id会被恶意猜测到数据的变化,所以重要id要用一个序列串

实现:保存某个时间的时间错,减去当前的。即可获得时间序列。
获得自增id,为了保证不重复性,根据日期以天的形式对自增id进行刷新。然后左翼32位通过或操作返回序列号
alt text

返回的值是一个64位,因为long的长度是64,首位会补0

优惠卷

使用优惠卷
alt text

引发线程安全问题
alt text

乐观锁适合更新数据,而不是插入数据
alt text

乐观锁解决--CAS:
在写操作时才进行判断是否写
alt text

优惠劵--一人一单

使用synchronized实现悲观锁。
alt text

alt text

出现问题:多台服务器下,服务器间线程无法干预
alt text
使用分布式锁解决
alt text
alt text

出现问题2:当运行的时间操过过期时间,再执行删除时会将其他线程的锁删除,故在删除锁前判断锁是否属于自己。
alt text

实现:根据线程id为标识执行setnx的操作,观察锁是否被使用
解析:redis的键为用户,保证setnx单个用户只能有一把锁。值为线程id(uuid),保证了不会出现误删,防止因为时间缓慢等操作导致执行删除操作时属于自己的线程锁过期,而删除了其他的线程锁。
alt text
alt text
alt text

出现问题3:确定是自己准备进行删除时发生了延迟,导致过期又没能删除正确的。理由:非原子性,需要保证命令是一次性全部执行完,才会进行其他操作。
alt text

解决:实用lua脚本
有key和argv2个数组,第一元素是在1的位置
alt text
java实现:
设置脚本参数
alt text
在执行redis命令时携带,则会将lua脚本的命令执行,实现redis,同时支持传参数

alt text

结合redisson

可重入锁

问题产生:一个线程多次对一个锁判断,如果使用上面的setnx无法实现。
alt text

实现思路:
将redis的储存转为hash多一个value的值。在进行锁判断时要进行一个锁是否为自己的判断,所以setnx失效,同时使用value的+-实现锁的多次读取。
alt text

lua脚本--获取锁
使用了hexists先判断锁是否是自己。(用于判断一个hash值是否存在)
alt text

lua脚本--释放锁
alt text

settNx的不好
alt text

异步的操作--优化秒杀

前提:商品卷的数据都要永久保存在redis中
alt text
1.在执行写操作等耗时久的操作分离出去。
alt text
alt text

alt text

实现:
通过lua判断后确认可以下单,生成要向数据库添加的信息后加入到阻塞队列中
alt text
alt text
在redis中确认可以实现操作后,将要保存传入异步操作,进行异步处理。
在init保证资源加载成功后启动这个线程,通过阻塞队列的方式,当队列有数据时开始对数据库进行操作
alt text

redis消息队列实现秒杀

将队列存入jvm中会带来错误,比如用户以为已经成功,但是jvm崩溃导致异步队列的数据无法完成等操作。故借助redis队列实现
alt text

基于list的消息队列

lpop和blpop的区别
alt text
alt text

好处:存入到redis中是数据的持久化,就算宕机后再次启动数据仍然存在。
坏处:取出后处理过程中失败,会导致数据失效。队列的数据只允许被拿走一次。
alt text

基于pubsub的消息队列

alt text
优缺点
alt text

基于stream的消息队列

alt text
alt text
alt text
alt text
alt text

基于消息组
alt text
alt text

alt text

多个消费者在一个组内去操作一个消息队列。
将队列和组建立关联。
消费者从组中读数据,实际上是从队列s1中读取数据。末尾是 >
表示读取那些还没有被消费的队列数据
alt text

通过ack从pending-list中确认数据
alt text
查看pending-list中剩余数据
alt text
当读取的方式是读取第一个 末尾是0,会读取处于消息队列的第一个元素。这种形式就算被读取了,下次读取仍然是k6 v6,因为在pendlist中没有被处理。当ack处理后将从消息队列中消失。
alt text

alt text
alt text

实现:XGROUP CREATE stream.orders g1 9 MKSTREAM

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/887394.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

APISIX

ApiSix 使用ApiSix网关作为所有业务的流量入口,它提供了动态路由、动态上游、动态证书、A/B测试、灰度发布、限速、防攻击、收集指标、监控报警、可观测、服务治理,服务熔断身份认证等功能。主要用于管理和控制API流量,安全性,性能和可用性,APIsix的主要作用包括:API管理…

ES

ES参考文档:https://www.cnblogs.com/buchizicai/p/17093719.htmlES分布式搜索引擎注意:在没有创建库的时候搜索,ES会创建一个库并自动创建该字段并且设置为String类型也就是text什么是elasticsearch?一个开源的分布式搜索引擎,可以用来实现搜索,日志统计,分析,系统监控…

【codeforces】codeforces界面字体突然变得很大,页面布局改变解决办法

今天打开codeforces界面突然变成了这样左侧变成了这样恢复方法: 把滚轮拉倒最下面切换成电脑模式即可恢复正常

影刀RPA与Coze API的结合使用

网上找了些资料,但是发现好多都是用的 Coze 的历史接口,现在新的 V3 接口处理方式包括字段和处理方式都不一样了,所以现在这个教程是基于最新版 V3 接口的。配置好 API 后,在影刀 RPA 中使用。 一、API 介绍 开发文档 : https://www.coze.cn/docs/developer_guides/coze_a…

RPA与Coze API的结合使用

网上找了些资料,但是发现好多都是用的 Coze 的历史接口,现在新的 V3 接口处理方式包括字段和处理方式都不一样了,所以现在这个教程是基于最新版 V3 接口的。配置好 API 后,在影刀 RPA 中使用。 一、API 介绍 开发文档 : https://www.coze.cn/docs/developer_guides/coze_a…

电脑感觉速度比以前慢,清理了还是慢怎么办?你需要检查下CPU频率,看看是不是被锁频/降频了

0 问题 电脑总是感觉速度慢,清理了电脑,去掉了不必要的程序,还是感觉没有以前快。 我的是笔记本电脑,电脑外壳各个地方摸起来也不热,风扇转动正常。也没有灰尘,清理过。 1. 原因 一直也不知道咋回事,看系统进程时,无意中看到CPU频率仅有0.4GHz,且长期都是这样,这肯定不…

【模拟电子技术】45-信号转换电路

【模拟电子技术】45-信号转换电路 串联电流负反馈,下面的电路起到的作用是使得Io与RL无关,下面也是负反馈定性分析:RL增大,Io增大,Ro右侧电压下降,A1的同相输入端减小,Uo1减小,Io减小 定量分析:(R1=R2=R3=R4)电压并联负反馈最后是全波精密整流电路,老师说这种电路对…

2025.02.20

pjudge 太坏了密码的 pjudge 怎么这么坏,怎么交题不显示代码的。 vp,第一次打 pjudge,最后看到没显示代码慌了,然后乱交代码,把 t1 整 0 了。真的流汗了,我为什么这么唐。我 t2 又是怎么 75 的呢?🤓省流:没遍历 id 为 0 的边。 以后再也不写成 tot = -1 了😡。

ViT, Transformer架构出圈到cv

Vision Transformer(ViT)通过采用自注意力机制处理图像块,革新了图像识别方法,展现了在大规模数据集上超越传统卷积神经网络的潜力。一、技术背景 视觉识别的挑战与机遇 在Vision Transformer(ViT)提出之前,卷积神经网络(CNNs),如ResNet和VGG,主导了视觉识别领域。然…

k8s面

题1:Kubernetes Service 都有哪些类型? 通过创建Service,可以为一组具有相同功能的容器应用提供一个统一的入口地址,并且将请求负载分发到后端的各个容器应用上。其主要类型有: ClusterIP:虚拟的服务IP地址,该地址用于Kubernetes集群内部的Pod访问,在Node上kube-proxy通…