分布式消息系统如何应对秒杀场景的挑战?

分布式消息系统秒杀

一、秒杀系统的核心问题与基本要求

分布式消息系统秒杀

1. 核心问题

并发读:优化理念是减少用户到服务端来“读”数据,或者让他们读更少的数据,通过缓存热点数据,减少数据库的频繁读取。

并发写:在数据库层面独立出一个库,做特殊处理,如设计专门的表,精简表字段。

2. 基本要求

高性能:涉及大量并发读写,可以从缓存、消息队列、请求削峰等角度进行设计。

一致性:保证秒杀减库存中的数据一致性。

高可用:保证系统的高可用和正确性,设计PlanB进行兜底。

二、架构原则

分布式消息系统秒杀

数据要尽量少:用户请求与响应的数据尽可能得少,可以减少数据序列化与反序列化的性能损耗。

请求数要尽量少:减少或合并css/java script、图片以及Ajax请求等,TCP三次握手,DNS解析等都会有资源消耗。

路径要尽量短:用户发出请求到返回数据这个过程中,需求经过的中间节点数尽可能少,尽可能使用RPC调用,提升系统性能。

依赖要尽量少:依赖指的是要完成一次用户请求必须依赖的系统或者服务。

不要有单点:无论是系统资源还是数据资源在设计的时候一定要考虑冗余。

三、秒杀系统的实现方案

1. 分布式限流

采用Sentinel的方式进行分布式限流,诸如warm up(预热)、拒绝、匀速排队等手段。

分布式消息系统秒杀

2. 负载均衡

对系统进行微服务化,拆分成商品中心、用户中心、订单中心,以实现负载均衡。

3. 缓存的使用

对热点数据(遵循二八原则)并且对实时性要求不高的数据进行缓存处理,如商品的基本信息。

4. 消息队列的使用

针对可以异步处理的操作,如下单,采用消息队列的方式进行处理,实行流量削峰。

5. 分布式锁

进行抢购时采用分布式锁的方式保证不会出现“超卖现象”。

四、如何防止“超卖”现象

秒杀系统防止的“超卖”的关键在于减库存的方式,通常有三种:

下单减库存:一定不会出现超卖情况,但是有些人下单完不付款会影响其他人。

付款减库存:付款减库存,可能会因为并发高导致付款时已经卖光,付不了款。

预扣库存:最常用,如下单后扣库存,保留十分钟,在十分钟内未付款就不保留,如果付款时发现库存不足则不允许付款,预扣库存存在“黄牛抢单”恶意抢单的情况,可以通过信誉积分、设置最大购买数、已有未支付订单不允许再次下单等方式进行控制,预扣库存通常使用分布式锁来实现。

技术方案包括:

setnx的方式:实现分布式锁,在获取锁,进行查库存 -> 创建订单 -> 扣减库存(并不会对库存数量进行上锁),这种方案将实现请求的序列化,但是并发量有限。

分段锁:进行抢购,可以借鉴LongAdder的实现,通过订购时随机分配一个分段锁,如果该分段库存不足,要自动释放锁,切换到一下分段库存尝试获取锁,分布式锁不会保存库存数量,获取锁只是获取购买销售品的资格,库存数量由数据库控制。

五、解决订单过期库存回库问题

解决订单过期库存回库的潜在方案包括:

后台线程不断扫描数据库:性能极低,弃用。

将订单数据存入Redis中并设置失效时间:考虑到要保留订单信息,弃用。

使用delayedQueue延时队列:设置到期时间,其中的对象只能在到期时才能从队列中取走,进行过期操作,但是不支持分布式,弃用。

使用RabbitMQ延迟队列:并使用定时任务处理可能的消息丢失导致的库存无法释放,采用。

六、如何解决用户重复订购问题

用户重复订购可以理解为请求幂等性的实现:

使用数据库唯一键:在锁座表中,设定场次Id和座位Id作为唯一键,锁定座位时,如果座位已经售卖,会报出数据库异常,不允许某一个座位重复售卖。

基于Redis实现:使用set操作具有天然的幂等性,当业务处理完再删除对应的key。

先查一次数据:来判断是新增操作还是更新操作。

前置布隆过滤器:向数据库前置一个布隆过滤器来判断数据是新数据还是旧数据,再使用主键索引来实现。

状态机:使用状态机来保证幂等性,订单状态可以有初始化、订购中、订购失败、订购成功,从而限制重复订购。

前端订单幂等性校验:对于前端的订单采用token幂等性校验,防止重复点击或者网络原因导致重复提交,外部接口的请求采用外部订单号做幂等性校验。

借助消息队列的串行化:借助第三方的幂等性校验,也能保证我们业务上的幂等性。

相关问题与解答

问1:什么是分布式锁?它是如何在秒杀系统中应用的?

答1:分布式锁是一种在分布式系统中用于控制多个进程或节点对共享资源的访问的机制,在秒杀系统中,分布式锁常用于控制对热点商品库存的访问,以防止并发操作导致的数据不一致问题,在用户下单时,通过分布式锁确保同一时间只有一个用户的请求能够修改库存数据,其他用户的请求则需等待锁释放后再进行操作,这有效避免了“超卖”现象的发生。

问2:为什么需要使用消息队列来处理秒杀系统中的订单?

答2:在秒杀系统中,由于瞬时并发量极大,直接操作数据库可能会导致系统崩溃或响应缓慢,消息队列作为一种异步处理机制,可以有效地削峰填谷,缓解系统压力,当用户发起秒杀请求时,系统先将请求消息放入消息队列中,然后由后台服务逐步从队列中取出消息进行处理,这样既可以保证用户请求的快速响应,又可以避免数据库因瞬间高并发而崩溃,提高了系统的稳定性和可扩展性,消息队列还支持持久化和重试机制,确保消息不丢失且最终被处理。

各位小伙伴们,我刚刚为大家分享了有关“分布式消息系统秒杀”的知识,希望对你们有所帮助。如果您还有其他相关问题需要解决,欢迎随时提出哦!

原创文章,作者:K-seo,如若转载,请注明出处:https://www.kdun.cn/ask/666336.html

Like (0)
Donate 微信扫一扫 微信扫一扫
K-seo的头像K-seoSEO优化员
Previous 2024-11-23 12:06
Next 2024-11-23 12:09

相关推荐

  • redis订单超时取消功能怎么实现的

    create_time = int 60 * 60 1小时前创建的订单。答:可以使用Redis的SETNX命令实现分布式锁,SETNX命令用于设置一个只有在键不存在时才设置的键值对,SETNX lock_key value,其中lock_key是锁的键,value是锁的值,当多个客户端尝试获取锁时,只有一个客户端能够成功设置锁的值,其他客户端会因为SETNX返回0而失败,这样就实现了分布式

    2023-12-28
    0115
  • kafka基础知识

    Kafka的知识点汇总Kafka是一个分布式流处理平台,主要用于构建实时数据流管道和应用程序,它具有高吞吐量、低延迟、可扩展性和容错性等特点,广泛应用于大数据、实时数据分析、日志收集等场景,本文将对Kafka的相关知识进行汇总,帮助大家更好地理解和使用Kafka。Kafka的核心概念1、Topic:主题(Topic)是Kafka中消息……

    2024-01-03
    0113
  • 如何安全地实现Redisson分页?

    安全Redisson分页一、引言在分布式系统中,为了保证数据的一致性和避免并发冲突,经常需要使用分布式锁,Redisson是一个基于Redis的Java驻留库,提供了丰富的分布式对象和服务,其中包括分布式锁,本文将详细介绍如何使用Redisson实现分页锁,以提高系统的并发性能和数据安全性,二、什么是分页锁?分……

    2024-11-18
    03
  • 公网消息队列_消息队列

    公网消息队列是一种分布式消息处理系统,允许应用程序通过互联网进行异步通信。它提供了一种可靠、可扩展和容错的方式来传递消息。

    2024-07-02
    090
  • redis分布式锁 redlock

    Redis分布式锁Redlock的实现在分布式系统中,为了保证数据的一致性,我们通常会使用分布式锁来对共享资源进行同步访问,Redis作为一种高性能的内存数据库,可以很好地实现分布式锁,Redlock算法是Redis作者Antirez提出的一种基于Redis的分布式锁实现方案,本文将详细介绍Redlock算法的原理和实现方式。1、Re……

    2024-03-12
    0166
  • redis并发读写不一致性怎么解决的

    Redis是一个高性能的内存数据库,支持并发读写操作,在高并发场景下,可能会出现并发读写不一致性的问题,为了解决这个问题,可以采用以下几种方法:1. 使用事务(Transaction):Redis提供了事务功能,可以将多个命令打包成一个事务进行处理,通过使用事务,可以确保一系列命令的原子性执行,从而避免并发读写不一致性的问题。2. 使……

    2023-11-14
    0143

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

免备案 高防CDN 无视CC/DDOS攻击 限时秒杀,10元即可体验  (专业解决各类攻击)>>点击进入