0%

系统设计

秒杀系统

巨大的瞬时流量

秒杀系统的特点,就是几乎所有的请求会集中到同一时刻,这种场景会在短时间内产生巨大的流量。

  1. 验证码:验证码可以拦截掉机器人发出的请求,可以起到防刷作用。也可以延缓并发,因为有的用户手速快,有的手速慢,可以让一瞬间的集中流量平均到5~10秒。

  2. 消息队列:可以把请求暂存到消息队列中,让服务根据自己的处理能力来消费请求,避免大量请求直接进入后台。

  3. 限流:限流就是通过校验,丢弃掉多余流量,减少下游服务需要处理的请求数量。

    • Nginx限流:Nginx自带限流功能,可以根据IP地址或者自定义参数来做限流。

      比如可以限制每个IP只能发送一个请求,或者每个用户ID只能发送一个请求。

    • 线程池限流:通过配置线程池的最大线程数,当等待队列满了,并且所有线程都处于工作状态,多余的请求就会被丢弃,也可以实现限流。

流量隔离

参与秒杀活动的商品通常只占很少一部分,为了不影响普通商品的交易,需要对流量进行隔离。

  • 商品打标:可以通过对秒杀商品打上特殊的标签,然后在网关层将秒杀商品的请求路由到对应的秒杀服务。

热点数据问题

对于秒杀系统,大家抢购的通常都是同一件商品,不管是用数据库,还是用缓存,都无法支撑几十万、上百万对同一个key的读写。

Redis最高只能支撑几万的TPS。

热点数据可以分为读热数据写热数据

  1. 读热数据:可以把热点数据加载到本地缓存中,需要注意的是本地缓存会导致数据延迟,可以通过调整本地缓存的有效期降低数据不一致的时间。
  2. 写热数据:先把库存数据同步到Redis中,通过Lua脚本把校验库存、扣减库存的命令打包到一个脚本中,发送给Redis执行。Redis扣减库存成功后,再通过异步将数据保存到数据库中。