• 秒杀系统该如何设计才更合理?
  • 发布于 1个月前
  • 57 热度
    0 评论
前言
最近有位好友问我,如何从整体角度,去设计一个秒杀系统。秒杀系统主要有这几个特征:
1.瞬时间的流量特别高。过了秒杀的时间,流量就会瞬时结束
2.大批量用户同时请求极少数商品

3.在秒杀时间前,可能会有很多请求过来。比如在11点抢票开始,10点59分你可能会提前去刷新页面请求。


所以特意写篇文章给大家说说。秒杀系统,应该满足哪些方面:
1. 满足高并发,快速响应
秒杀系统的瞬时流量特别大,为了防止系统被打垮了,一般要做压测。测清楚你的系统支撑的最大并发是多少,确定系统的瓶颈点,让自己心里有底,最好预防措施。压测完要分析整个调用链路,性能可能出现问题是网络层(如带宽)、Nginx层、服务层、还是数据路缓存等中间件等等。要快速响应,前期还可以做一些优化。比如页面资源静态化、缓存热数据预加载、CDN加速等等。

2. 防止超卖
做秒杀系统,最主要就是防止超卖问题。所以是要加分布式锁的。一般都是用Redis分布式锁。但是呢,使用redis分布式锁,可能会有坑的,否则也是可能导致超卖问题。比如要注意这些常见redis分布式锁的坑:
非原子操作(setnx + expire)
被别的客户端请求覆盖( setnx + value为过期时间)
忘记设置过期时间
业务处理完,忘记释放锁
B的锁被A给释放了
释放锁时,不是原子性
锁过期释放,业务没执行完
Redis分布式锁和@transactional一起使用失效
Redis主从复制导致的坑

3. 防止恶意刷子
一般秒杀系统,都是大多数人去抢比较有价值的商品。有些黄牛可能会写脚本模拟发大批量请求,从而导致真正的用户抢不到。这时候,一般需要加入黑名单或者限流处理,比如限制用户多次请求,或者限制IP等等。比如一个用户最多只能请求5次,一个IP最大请求10次等等。

4. 页面静态化
秒杀流程是这样的:

如果所有的前端请求,都打到服务端,服务端压力比较大。实际上,一些请求只是访问比如商品名称、商品图片等资源。这些请求没必要跟后端交互,可以做页面静态化。也就是说,对页面缓存,用户请求URL的时候,请求不再打到服务端,直接找到静态服务资源即可。

如果用户在全国各地的话,单纯把页面静态化还不是最优解。还可以将静态资源(如图片、CSS、JS)分发到 CDN 节点,它通过就近分发原则,可以提高资源的响应速率。

CDN(Content Delivery Network,内容分发网络)是一种通过在全球范围内部署的服务器节点,帮助网站和应用程序快速、可靠地将内容传递给用户的技术。其主要目的是加速内容的加载速度,降低网络延迟,提高用户体验。

5. 秒杀开关,比如秒杀按钮开关置灰
比如我们要抢某个时间点的高铁票,我们因为害怕错误抢票的最佳时间,往往会提前进到抢票界面。 即使,还没到抢票时间点,但是我们看到抢票按钮可以点击的话,我们都会去多点几下。。。

如果抢票按钮没置灰的话,会提前有很多请求到服务端,这样服务端压力大很多。所以,为了秒杀开始前,过滤无效的请求到服务端,可以把秒杀按钮置灰。

6. MQ 流量削峰、异步处理
回忆一下什么是同步,什么是异步呢?以方法调用为例,它代表调用方要阻塞等待被调用方法中的逻辑执行完成。这种方式下,当被调用方法响应时间较长时,会造成调用方长久的阻塞,在高并发下会造成整体系统性能下降甚至发生雪崩。异步调用恰恰相反,调用方不需要等待方法逻辑执行完成就可以返回执行其他的逻辑,在被调用方法执行完毕后再通过回调、事件通知等方式将结果反馈给调用方。

因此,对于秒杀系统,后端可以借用MQ来做流量削峰。在海量秒杀请求过来时,先放到MQ消息队列中,快速响应用户,告诉用户请求正在处理中,这样就可以释放资源来处理更多的请求。秒杀请求处理完后,通知用户秒杀抢购成功或者失败。对于秒杀成功的请求,因为还有下单、支付等操作,还可以使用MQ做异步处理。就是把秒杀成功的消息放到MQ,下单等后续操作异步处理。

7. 失败补偿
如果秒杀成功消息已经记录,我们就要保证订单一定要处理成功。如果订单创建失败了,我们要做好监控和告警措施。同时有一定的失败重试机制。

8. 限流
秒杀系统,会存在瞬时大流量过来。我们当然希望,系统能全部请求都正常处理。但是有时候没办法,系统的CPU、网络带宽、内存、线程等资源都是有限的。因此,我们要考虑限流。如果你的系统每秒扛住的请求是一千,如果一秒钟来了十万请求呢?换个角度就是说,高并发的时候,流量洪峰来了,超过系统的承载能力,怎么办呢?这时候,我们可以采取限流方案。就是为了保护系统,多余的请求,直接丢弃。

什么是限流:
在计算机网络中,限流就是控制网络接口发送或接收请求的速率,它可防止DoS攻击和限制Web爬虫。限流,也称流量控制。是指系统在面临高并发,或者大流量请求的情况下,限制新的请求对系统的访问,从而保证系统的稳定性。可以使用Guava的RateLimiter单机版限流,也可以使用Redis分布式限流,还可以使用阿里开源组件sentinel限流。

面试的时候,你说到限流这块的话?面试官很大概率会问你限流的算法,因此,大家在准备面试的时候,需要复习一下这几种经典的限流算法哈,可以看下我之前的这篇文章,面试必备:4种经典限流算法讲解

9. 服务降级
服务降级是一种在系统负载过高或者出现故障时,为了保证核心功能的可用性而暂时关闭或者限制一些非核心功能的策略。

在秒杀系统中,如果突然有大量用户涌入,会对系统的性能和可用性造成巨大压力。如果不进行服务降级,系统可能会因为超负荷而崩溃,导致用户无法完成购买,这对于商家来说是极为不利的。因此,通过服务降级,可以暂时关闭一些非关键功能,如用户评论、商品推荐等,以保证核心功能——即完成购买的流程,能够正常运行。
用户评论