秒杀系统
2021-08-14 18:44:36 10 举报
系统框架
作者其他创作
大纲/内容
秒杀请求
原因:消息消费失败,导致不能回调状态变更接口,这样job会不停的重试发消息,最终产生大量垃圾
2.负载均衡,将请求转发给各个Tomcat,进行一次分流
使用lua脚本保证查询与扣减操作的原子性,阻止超卖问题
消息放入延迟队列中,定时30min去redis中查询订单
消息发送表和消息处理表都由redis中订单实现,消息发送时会在redis中存放订单,如果消息丢失,那么会定期扫描redis中的订单,对时间超过30分钟且已支付的消息,再次发送消息消息处理后会删除redis中的订单,那么消息不会发送重复消费,消息放在延迟队列中进行延迟消费,定时去查看redis中该订单的状态,对于垃圾消息,会每次发送的时候时候检测消息的发送次数,超过一定次数,不再发送。
先去访问一个controller @GetMapping(\"/getSeckillSkuInfo/{skuId}\"),判断是否到达指定时间,到达后会生成一个商品随机码,发送给前端,前端带着这个随机码去对指定商品进行秒杀
重复消费
消息丢失
商品库存缓存于Redis中,查询商品是否有库存并扣减库存,于Redis中
原因:网络问题、broker挂了、mq服务器磁盘问题等
库存预热
1.拦截器鉴权:用户是否登录 2..判断秒杀链接是否正确,3.秒杀订单是否存在
创建一张消息处理表,消费者读取到消息后,先判断消息是否存在,如果存在,则表示为重复消息,则返回。如果不存在,则进行下单操作,接着将该消息写入消息处理表中,再返回。有个比较关键的点是,实际下单和写消息处理表要在同一个事物中,保证在同一事物中,保证原子操作
原因:本来消费者消费消息时,用ack应答的时候,如果网络超时,本身就可能会消费重复消息,但由于消息发送者增加了重试机制,会导致消费者重复消息的概率增加
解决方案:创建一张消息发送表,在生产者发送MQ消息前,先把该消息写入消息发送表,初始状态是待处理,然后在发送Mq消息。消费者消费消息时,处理完业务逻辑后,再回调生产者的一个借口,修改消息状态为已处理。如果生产者把消息写入消息发送表后,再发送MQ消息到MQ服务端的过程中失败了,造成消息损失,此时可以通过job,增加重试机制,每隔一段时间,job去查询消息发送表中状态为待处理的数据,然后重新发送MQ消息
如果用户秒杀成功了,创建订单于redis中,在30分钟未完成支付,订单将自动取消。
1.动静分离,将静态资源放在static文件下,不需要去请求tomcat服务器
扣减预库存成空,创建订单
1.拒绝重复订单 2.支付成功后需要修改redis中订单状态
消息队列使用手动确认模式保证消息的可靠到达
延迟消费
RabbitMQ进行消息的异步响应
Nginx服务器
订单保存于redis中,以用户id_skuid:订单信息的形式存储
解决方案:每次在job重试时,判断消息发送表中该消息的发送次数是否达到最大限制,如果达到了,则直接返回。如果没有达到,则次数+1,然后发送消息
服务器层限流
GateWay
如果存在此订单且如果订单的状态为已支付,则进行数据库扣减库存,否则删除此订单消息,并将redis库存回滚
订单创建完成后,将消息放入延迟队列中。用户支付完成后,修改支付订单的状态为已支付
发送消息到队列中,如果没有问题,则返回正确信息
路由到秒杀服务,单一职责,放置秒杀服务崩溃,影响其他服务
收藏
0 条评论
下一页