当前位置: 首页 > news >正文

【系统架构】如何设计一个秒杀系统?

目录

1. 什么是秒杀?

2. 秒杀系统的特点

3. 如何设计秒杀系统?

3.1 前端秒杀设计

3.2 后端秒杀设计

4. 如何保证不超卖?

4.1 库存扣减方式

4.2 服务端库存处理

5. 总结

* 知识扩展:什么是CDN?


1. 什么是秒杀?

所谓秒杀,就是在同一个时刻有大量的客户端请求争抢同一个商品并完成交易的过程,瞬时会产生大量的并发读和并发写。

秒杀系统本质上就是一个满足高并发高性能高可用的分布式系统,下面给出一张下单交互概要图:

2. 秒杀系统的特点

高性能

秒杀涉及大量的并发读和并发写,因此秒系统必须能支持高并发访问,而且RT(响应时间)需要在一定的范围内,通常是200ms

一致性

秒杀系统中通常会使用缓存,如何保证缓存和数据库中库存数据的一致性,保证商品库存的准确性

高可用

秒杀系统会在瞬间收到大量的读写操作,如何能保证服务能稳定的运行,设计系统时是否考虑到系统容灾问题,保证服务的高可用

可扩展性

当服务达到瓶颈时,如何能实现快速扩容

 

3. 如何设计秒杀系统?

从在上述秒杀概要图中,我们可以知道,整个秒杀流程需要从前端和后端2个核心部分进行,因此我们就从这 2个部分来讲解秒杀系统是如何设计的。

3.1 前端秒杀设计

服务高可用

前端是秒杀的入口,用户首先是到前端界面进行商品浏览,然后加购自己想要的商品进行下单付款操作。 所以,前端服务一定要保证高可用,要不然秒杀的入口都没有了,谈何秒杀。

页面静态化

前端数据源动静分离,静态的数据可以放到CDN,前端从CDN获取,动态的数据放到服务器。 静态数据,比如商品的详情信息,图片等;动态数据,商品的数量,价格等。 比如:可以通过Url地址作为key来存储静态数据

控制对服务器请求的频率

控制对服务器请求频率能在一定程度上缓解服务器的压力,限频的方式有很多, 比如 秒杀按钮点击后置灰一定的时长后才能再次点击, 前端 答题正确后才向服务器发起请求,前端将请求加入队列进行排队,当有多个秒杀活动时,可以分时段进行,这些方式都是无损的。

控制对服务器请求参数的大小

因为秒杀期间,瞬时会有大量的请求涌向服务器,所以前端和服务器的数据交互要尽量的少,减少网络传输以及编解码的开销。

限流,降级

当下游服务器达到瓶颈时,可以采用前端限流方式,降低对服务器的TPS和QPS。但是当客户端比较分散时,限流阈值的设置是一个比较大的挑战:阈值设的太小,会导致服务端没有达到瓶颈时客户端已经被限制;设的太大,则起不到限制的作用。

3.2 后端秒杀设计

服务高可用

后端是处理请求的核心服务,所以必须做好高可用部署,容灾设计(异地多活)

降级,限流,拒绝服务

降级,就是当系统的容量达到一定程度时,限制或者关闭系统的某些非核心功能,从而把有限的资源保留给更核心的业务。所以降级一般需要前后端配合执行,可以通过开关系统来实现。比如: 当QPS达到一个阈值时,可是设置开关,将原来分页查50条数据,变成查10条,减少一次交互的数据量

限流,就是当系统容量达到瓶颈时,通过限制一部分流量来保护系统,限流可以是接口级别,服务器级别,iP级别等等,此处的限流是有损操作,限流的阈值一般可以根据压测结果来设置

直接拒绝服务,如果限流还不能解决问题,那就直接拒绝服务以求自保,这也是最差的一种兜底情况。

独立部署秒杀服务

秒杀系统和普通的售卖有一定的差异点,秒杀一般是持续时间短,并发量高,所以为了不影响正常的售卖,可以单独部署一套秒杀服务,在物理级别进行隔离,也适合服务端灵活伸缩容以及做一些特殊的个性化处理。 有条件的团队可以实施。

流量削峰

当服务流量过大时,可以将请求存入MQ消息中间件进行削峰处理,客户端可以采用轮询的方式向服务器获取结果(服务器会受到很多结果查询的请求),或者服务主动push结果给客户端(服务需要保留很多和客户端的长链接),2种方式各有优劣,一般生产上轮询查询结果用的比较多。

热点数据探测

很多时候,一个商品不属于秒杀,但是很多用户购买,可能会成为热点数据,请求量不亚于秒杀,所以网关需要有热点数据探测的功能,实现的方式有很多,比如:统计客户端的请求数

增加缓存

秒杀一般遵从读多写少的28法则,所以可以在服务端增加缓存应对高并发读。缓存可以设置2层,第一层是本地缓存,可以使用Google guava的缓存框架,失效时间一般可以秒级别,本地缓存是属于jvm级别的,每次失效后可以从redis缓存中加载,redis缓存要特别注意缓存失效,缓存击穿,缓存雪崩的问题。

缓存击穿:缓存中不存在,数据库存在,这样就会导致请求直接到达数据库,当请求量比较大时,可能直接把数据库打垮。解决方法:

  1. 可以考虑缓存永远不过期

  2. 同步返回null,异步加锁查询数据库,更新缓存

缓存穿透:请求的数据在缓存和数据库中都不存在,解决办法:

  1. 业务层进行合法校验,拦截大部分不合法的请求

  2. 使用布隆过滤器,针对一个或者多个维度,把可能存在的数据值hash到bitmap中,bitmap中不存在则该数据一定不存在,bitmap中存该数据可能存在

  3. 对空的结果进行缓存,设置得较短过期时间,当有数据库变更时,必须同时刷新缓存,否则会导致不一致的问题存在

缓存雪崩:指缓存在同一时刻失效,请求都到数据库上,解决的办法:

  1. 可以考虑缓存永远不过期

  2. 失效时间尽量随机,避免同时过期

  3. 多级缓存,数据缓存到A和B,A设置过期时间,B不设置过期时间,如果A为空的时候去读B,同时异步去更新缓存,需要同时更新两个缓存

4. 如何保证不超卖?

4.1 库存扣减方式

下单减库存:买家下单后,扣减商品总库存。下单减库存是最简单也是控制最精确的一种,下单时直接通过数据库的事务机制控制商品库存,一定不会出现超卖的情况。出现的问题: 恶意刷单,某些人下单后占用库存不付款。

付款减库存:买家付款之后,扣减商品总库存。这种方式产生的问题是,库存超卖。

预扣库存:买家下单后,预扣库存,在一定的时间内未付款,库存将会自动释放。在买家付款前,需再次校验库存是否保留,如果没有保留,则再次尝试预扣;如果库存不足则不允许继续付款;如果预扣成功,则完成付款并实际地减去库存。这种方式在生产上用的比较多。

4.2 服务端库存处理

将库存操作的逻辑放到lua脚本中,通过redis的单线程特性,保证Lua脚本执行不会被打断,从而保证库存操作的原子性

5. 总结

下面给出一张秒杀系统常用的架构图,百种业务百种架构,一个秒杀系统看似简单,其实包含了很多架构的思想,从前端到后端,怎么全局把控,对于各个服务怎么去做高可用,高性能,可扩展保证。如何设计缓存,如何保证缓存和数据库的数据一致性,服务达到瓶颈时,如何做服务降级,限流。

一般我们遵从几个原则:

  1. 前后端交互的数据尽量少

  2. 前端尽量控制对后端的无效请求

  3. 服务之间的依赖尽量少

  4. 请求路径尽量短

  5. 服务或者中间件不要有单点,要有容灾

* 知识扩展:什么是CDN?

CDN(内容分发网络)是一种通过分布式服务器网络加速内容传输的技术。它通过将静态资源(如HTML、CSS、JavaScript、图片、视频等)缓存到全球多个节点服务器上,使用户可以从离自己最近的节点获取资源,从而提升加载速度和性能。

前端CDN的主要作用:

  • 加速资源加载:用户从最近的节点获取资源,减少延迟。

  • 减轻服务器负担:CDN分担流量,降低源服务器压力。

  • 提升可用性:即使某个节点故障,其他节点仍可提供服务。

  • 节省带宽:通过缓存减少重复请求,降低带宽消耗

常见的前端CDN服务:

  • jsDelivr:免费CDN,支持开源项目。

  • Cloudflare:提供安全防护和性能优化。

  • Akamai:全球最大CDN之一,适合大型企业。

  • AWS CloudFront:亚马逊的CDN服务,与AWS生态系统集成。

  • Google Cloud CDN:谷歌的CDN服务,与Google Cloud集成。

简单来说,前端CDN通过分布式缓存和就近访问,显著提升网站性能,改善用户体验,同时减轻服务器压力。



🌸🌸🌸 完结撒花 🌸🌸🌸

  博主WX:g2279605572   欢迎大家与我交流! 

 

相关文章:

【系统架构】如何设计一个秒杀系统?

目录 1. 什么是秒杀? 2. 秒杀系统的特点 3. 如何设计秒杀系统? 3.1 前端秒杀设计 3.2 后端秒杀设计 4. 如何保证不超卖? 4.1 库存扣减方式 4.2 服务端库存处理 5. 总结 * 知识扩展:什么是CDN? 1. 什么是秒杀…...

C++模拟实现queue

C模拟实现queue 1.queue的基本概念2.queue的基本框架3.size()成员函数4.empty()成员函数5.push()成员函数6.pop()成员函数7.front()成员函数8.back()成员函数9.完整代码 🌟🌟hello,各位读者大大们你们好呀🌟🌟 &#x…...

【2025小年源码免费送】

💖学习知识需费心, 📕整理归纳更费神。 🎉源码免费人人喜, 🔥码农福利等你领! 💖山高路远坑又深, 📕大军纵横任驰奔, 🎉谁敢横刀立马行…...

PyQt5 超详细入门级教程上篇

PyQt5 超详细入门级教程 上篇:1-3部分:PyQt5基础与常用控件 第1部分:初识 PyQt5 和安装 1.1 什么是 PyQt5? PyQt5 是 Python 的图形用户界面 (GUI) 框架,它基于强大的 Qt 库。Qt 是一个跨平台的 C 框架,用…...

qiankun+vite+vue3

基座与子应用代码示例 本示例中,基座为Vue3,子应用也是Vue3,由于qiankun不支持Vite构建的项目,这里还要引入 vite-plugin-qiankun 插件 基座(主应用) 加载qiankun依赖 npm i qiankun -S qiankun配置(src/qiankun) src/qiankun/config.ts export default {subApp…...

【数据结构】顺序队列与链式队列

顺序队列与链式队列 1.队列的基本概念1.顺序存储的队列:循环队列3.链式存储的队列:链式队列 1.队列的基本概念 队列是一种逻辑结构,是一种特殊的线性表 只能在固定的两端操作线性表 只要满足上述条件,那么这种特殊的线性表就会…...

Cursor的详细使用指南

以下是一份关于 Cursor 的详细使用指南: 一、安装与设置 下载与安装: 首先,访问 Cursor 的官方网站,根据你的操作系统(Windows、Mac 或 Linux)下载相应的安装程序。运行安装程序,按照屏幕上的提…...

2025美赛数学建模B题思路+模型+代码+论文

2025美赛数学建模A题B题C题D题E题思路模型代码(1.24第一时间更新,更新见文末名片) 论文数学建模感想 纪念逝去的大学数学建模:两次校赛,两次国赛,两次美赛,一次电工杯。从大一下学期组队到现在…...

2024年度总结-CSDN

2024年CSDN年度总结 Author:OnceDay Date:2025年1月21日 一位热衷于Linux学习和开发的菜鸟,试图谱写一场冒险之旅,也许终点只是一场白日梦… 漫漫长路,有人对你微笑过嘛… 文章目录 2024年CSDN年度总结1. 整体回顾2…...

2024国游销量前20游戏分析:某开放世界武侠(排名11)

1、销量约20万套,销售额1400万人民币。 与一代的发售间隔为三年。 虽然对于网游大厂来说这个数字不够看,但对一个小团队来说足够维持了,三年的运营成本不是小数目。 2、开发商属于国内最早做3DMMO的厂商之一,创始人曾在国外大学…...

如何使用python技术爬取下载百度文库文档?

使用 Python 爬取百度文库文档需要通过分析网页结构和接口请求来实现。以下是一个基于搜索结果的实现方法,适用于爬取百度文库中的文档内容: 第一部分:获取百度文库文档 实现步骤 获取文档 ID 和基本信息 通过文档的 URL 获取文档 ID&…...

navicat无法连接虚拟机的docker中的mysql

我的数据库安装在了虚拟机的docker中,启动MySQL后,在主机上使用navicat一直连接不上。 首先确认密码是否有问题: docker exec -it mysql8 bash #进入mysql容器 mysql -u root -p #登录MySQL,我这边密码是123456 密码没问题的话…...

如何使用CRM数据分析优化销售和客户关系?

嘿,大家好!你有没有想过为什么有些公司在市场上如鱼得水,而另一些却在苦苦挣扎?答案可能就藏在他们的销售策略和客户关系管理(CRM)系统里。今天我们要聊的就是如何通过有效的 CRM 数据分析来提升你的销售额…...

【Unity3D】3D物体摆放、场景优化案例Demo

目录 PlaceManager.cs(放置管理类) Ground.cs(地板类) 和 GroundData.cs(地板数据类) 额外知识点说明 1、MeshFilter和MeshRenderer的Bounds区别 2、Gizmos 绘制一个平行于斜面的立方体 通过网盘分享的文件:PlaceGameDemo2.unitypackage 链接: https://pan.baid…...

使用HTML5 Canvas 实现呼吸粒子球动画效果的原理

在网页开发领域,动画效果能够极大地提升用户体验,让页面变得更加生动有趣。今天,我们深入剖析一个基于 HTML5 Canvas 的 3D 粒子动画 —— 呼吸粒子球。通过详细解读其代码实现,我们将全面了解如何运用 HTML5 的强大功能构建出如此…...

Java 中实体类与操作类分离

目录 一、为啥要把实体类和操作类分开 二、实体类长啥样,怎么用 三、操作类的使命与实现 四、实战演练:实体类与操作类协同工作 五、拓展思考:这种分离带来的好处与进一步优化 六、总结与展望 家人们,今天我想跟你们唠唠我在…...

【STM32HAL-----GPIO】

1. 什么是GPIO?(了解) 2. STM32 GPIO简介 2.1. GPIO特点 2.2. GPIO电气特性 2.3. GPIO引脚分布图 IO引脚分布特点:按组存在、组数视芯片而定、每组最多16个IO引脚。 3. IO端口基本结构介绍 4. GPIO八种工作模式 4.1. 输入浮空 特…...

Java Web开发高级——单元测试与集成测试

测试是软件开发的重要环节,确保代码质量和功能的正确性。在Spring Boot项目中,单元测试和集成测试是常用的两种测试类型: 单元测试:测试单个模块(如类或方法)是否按预期工作。集成测试:测试多个…...

编译chromium笔记

编译环境: windows10 powershell7.2.24 git 2.47.1 https://storage.googleapis.com/chrome-infra/depot_tools.zip 配置git git config --global user.name "John Doe" git config --global user.email "jdoegmail.com" git config --global …...

Web开发 -前端部分-CSS3新特性

1 CSS概述 2 CSS3私有前缀 3 CSS3的长度单位 代码实现&#xff1a; <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度​

一、引言&#xff1a;多云环境的技术复杂性本质​​ 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时&#xff0c;​​基础设施的技术债呈现指数级积累​​。网络连接、身份认证、成本管理这三大核心挑战相互嵌套&#xff1a;跨云网络构建数据…...

【HTTP三个基础问题】

面试官您好&#xff01;HTTP是超文本传输协议&#xff0c;是互联网上客户端和服务器之间传输超文本数据&#xff08;比如文字、图片、音频、视频等&#xff09;的核心协议&#xff0c;当前互联网应用最广泛的版本是HTTP1.1&#xff0c;它基于经典的C/S模型&#xff0c;也就是客…...

docker 部署发现spring.profiles.active 问题

报错&#xff1a; org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...

力扣热题100 k个一组反转链表题解

题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...

mac:大模型系列测试

0 MAC 前几天经过学生优惠以及国补17K入手了mac studio,然后这两天亲自测试其模型行运用能力如何&#xff0c;是否支持微调、推理速度等能力。下面进入正文。 1 mac 与 unsloth 按照下面的进行安装以及测试&#xff0c;是可以跑通文章里面的代码。训练速度也是很快的。 注意…...

恶补电源:1.电桥

一、元器件的选择 搜索并选择电桥&#xff0c;再multisim中选择FWB&#xff0c;就有各种型号的电桥: 电桥是用来干嘛的呢&#xff1f; 它是一个由四个二极管搭成的“桥梁”形状的电路&#xff0c;用来把交流电&#xff08;AC&#xff09;变成直流电&#xff08;DC&#xff09;。…...

针对药品仓库的效期管理问题,如何利用WMS系统“破局”

案例&#xff1a; 某医药分销企业&#xff0c;主要经营各类药品的批发与零售。由于药品的特殊性&#xff0c;效期管理至关重要&#xff0c;但该企业一直面临效期问题的困扰。在未使用WMS系统之前&#xff0c;其药品入库、存储、出库等环节的效期管理主要依赖人工记录与检查。库…...

云原生时代的系统设计:架构转型的战略支点

&#x1f4dd;个人主页&#x1f339;&#xff1a;一ge科研小菜鸡-CSDN博客 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; 一、云原生的崛起&#xff1a;技术趋势与现实需求的交汇 随着企业业务的互联网化、全球化、智能化持续加深&#xff0c;传统的 I…...

【汇编逆向系列】六、函数调用包含多个参数之多个整型-参数压栈顺序,rcx,rdx,r8,r9寄存器

从本章节开始&#xff0c;进入到函数有多个参数的情况&#xff0c;前面几个章节中介绍了整型和浮点型使用了不同的寄存器在进行函数传参&#xff0c;ECX是整型的第一个参数的寄存器&#xff0c;那么多个参数的情况下函数如何传参&#xff0c;下面展开介绍参数为整型时候的几种情…...