千万级流量“秒杀”系统

2023-12-21 18:48:35

例如我有以下一个秒杀系统架构:

  • 用户层:用户端展现的部分,主要涉及商品的相关信息及当前 “秒杀活动的信息”

  • CDN层:缓存 “秒杀” 活动的静态资源文件。

  • 负载均衡层:拦截请求及分发路由等。

  • 服务层:“秒杀” 活动的相关逻辑处理。

  • 基础设施层:数据存储、大数据计算及消息推送等操作。

秒杀系统特点:

  1. 业务特点:

    • 在“秒杀”活动还没开始的时候,流量一直是很平稳的状态;

    • 当“秒杀”活动活动结束的后,流量又会急速下落。

    • 限时、限量、限价

    • 活动预热

    • 持续时间短

  2. 技术特点:

    • 顺时并发量高:“秒杀”活动商品限时、限量、限价的特性,决定了“秒杀”活动一开始就会出现流量洪峰,即瞬间并发量达到峰值。

    • 并发读写:“读”比“写”要多得多,是“读多写少”的场景。

    注意:在应对“秒杀”活动时,需要进行限流操作,利用流量的时间分片来缓冲瞬时的大流量。

秒杀活动设计原则

  1. 数据量应该尽量少。

    • 简化“秒杀”页面大小,去除一些不必要页面装饰。

    • 尽量提前预热。

    • 发送“秒杀”时只带上最有用的信息。

    • 在服务端返回数据时,返回最简数据体。

    • 减少依赖外部服务。

  2. 请求数应该尽量少(用户进入商品秒杀详情页时,浏览器会渲染各种额外数据,如CSS,文件图片等,这些信息需要减少)

  3. 请求路径尽量短

  4. 尽量使用异步化

  5. 避免单节点(将服务完全无状态化??)

动静分离方案设计

将静态页面和动态页面(静态数据和动态数据)解耦分离,用不同系统承载对应流量。提升整个副武的访问性能和可维护性。

什么是静态数据

页面中几乎不怎么变化的数据(即补一句用户的Cookie、基本信息、地域、时间、等各种属性来生成的数据),如:

  1. CSS和 JS 文件中静态数据

  2. 活动页中的 HTML 静态文件

  3. 图片等相关资源

什么是动态数据

依据当前用户属性动态生成的数据。。

处理动态数据体现在技术架构上采用:

  • 清晰的分层架构

  • 服务架构

  • 缓存架构

如何实施动静分离架构

分而治之,动态数据和静态数据解耦,分别使用各自的架构系统来承载对应的流量。

使用“页面静态化”技术实现动静分离架构

访问静态数据快,访问动态数据慢,提前生成好需要动态获取的数据,然后使用静态页面加速技术来访问这些数据。

页面静态化数据的介绍:直接缓存HTTP连接,而不是缓存数据。

适用场景:动态数据总量不是很大,生成的静态页面数量不多的业务

热点数据处理

例如:微博热点信息,淘宝热门商品

什么是热点数据

在一定时间内被大量用户访问的数据。

热点数据又分为:“静态热点数据” 和 “动态热点数据”:

  1. 静态热点数据:可以被提前预知的热点数据。

  2. 动态热点数据:不能被提前预知的数据。

如何如初热点数据

发现热点数据后一般做法是:优化、限制和隔离

  1. 热点数据的优化:直接将发现的热点数据写入分布式缓存,并且根据业务情况对其设置缓存过期时间。

  2. 热点数据的限制:热点数据的限制是一种保护系统的机制,目的是不让热点数据抢占其他请求的资源。

    • 例如:线程池隔离技术,将每个热点数据的处理放在独立的线程池内,这样可以避免大流量的冲击而影响其他请求使用机器资源。

  3. 热点数据的隔离:热点数据的隔离也是一种保护机制,不能因为数据量访问过大造成业务崩溃。

    • 例如:先将“秒杀”业务和其他主线业务隔离开,防止他们互相影响;然后,将“秒杀”系统独立部署,且使用独立的域名,最后,“秒杀”系统使用独立的数据库。

大流量的高效管理

由于瞬时的流量洪峰会带来严重的服务端 读/写 性能问题、数据库锁,以及服务器资源占用问题。

流量分层

流量分层控制

  1. CDN层流量控制

    • 由动静分离联系 —> 应该提前生成尽可能多的数据,然后将其放入到 CDN 节点缓存中(CDN在物理架构上离用户比较近)

  2. 反向代理层流量控制

    • 通过后端服务 Job 的方式定时提前生成好前端需要的静态数据,然后将其发送到内容分发服务上,内容分发服务会将这些静态数据分发给所有反向代理服务器。

后端服务层流量控制

  • 程序开发上,代码独立,不要与平台其他项目合在一起。

  • 在部署时,独立部署,分散流量,避免不适合的流量影响主题业务。

  • 使用独立域名,或按照一定的 URL 规则在反向代理层进行路由。

  • 做好系统保护和限流。

请求量超过最大请求限制,可以直接拒绝超过请求返回至 “秒杀” 结束信息。

数据库层流量控制

此处需要对数据库进行IO说明是下单成功的流量,有如下建议:

  • 如果不是临时的活动,建议使用独立数据库作为“秒杀”活动的数据库。

  • 将数据库配置成读写分离。

  • 尝试去除行锁。

    • 对于高并发的秒杀活动来说,这种行锁的机制可能会导致大量的线程阻塞,降低系统的吞吐量。特别是当秒杀活动开始时,大量的用户会同时请求同一条商品数据,如果使用行锁,那么每次只能有一个用户的请求被处理,其他的用户都需要等待,这会导致用户体验非常差,也会使得系统的响应时间大大增加。

    • 使用分布式锁

扣减库存相关问题

对于一般的购买过程,用户是不需要关心库存的。但是高并发情况下用户争抢库存,如果没有控制好就会出现超卖情况。

扣减库存的方式

  1. 下单后扣减库存:

    • 最简单,最好理解。

    • 用户下单后不付款,利用 “秒杀器” 恶意大量抢购商品。

  2. 支付后扣减库存:

    • 用户付完款后再扣减库存。

    • 也存在 “超卖” 问题,大部分付款之后也不会抢到。

  3. 预扣减库存:

    • 用户下完单后,系统会为其锁定库存一段时间;超过锁定时间后自动释放锁定的库存,让其他用户抢购。用户付款时会校验是否在有效期内,如果在则可以进行支付,若过期则会重新锁定,若库存不足,则返回提醒。

在千万级秒杀中如何扣减库存

由于在秒杀中使用 “下单后扣减库存” 这种方式更为合适,利用数据库的事务特性,可以保证订单和库存扣减数量的一致性

采用更新 “结果值” 的操作而并非直接更新 “扣减” 操作。“扣减” 不是幂等性的,如果接口设计不够完整,没考虑到“幂等性”就会由于网络原因或者其他原因造成重试后,会出现重复“扣减”,即“超卖”甚至库存为负值情况出现。

优化库存数量扣减
  1. 利用好缓存(Redis)

  2. 异步处理

文章来源:https://blog.csdn.net/weixin_74783792/article/details/135137004
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。