当前位置: 首页 > 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"…...

深入理解JavaScript设计模式之单例模式

目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式&#xff08;Singleton Pattern&#…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命

在华东塑料包装行业面临限塑令深度调整的背景下&#xff0c;江苏艾立泰以一场跨国资源接力的创新实践&#xff0c;重新定义了绿色供应链的边界。 跨国回收网络&#xff1a;废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点&#xff0c;将海外废弃包装箱通过标准…...

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...

2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)

安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...

CSS | transition 和 transform的用处和区别

省流总结&#xff1a; transform用于变换/变形&#xff0c;transition是动画控制器 transform 用来对元素进行变形&#xff0c;常见的操作如下&#xff0c;它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...

快刀集(1): 一刀斩断视频片头广告

一刀流&#xff1a;用一个简单脚本&#xff0c;秒杀视频片头广告&#xff0c;还你清爽观影体验。 1. 引子 作为一个爱生活、爱学习、爱收藏高清资源的老码农&#xff0c;平时写代码之余看看电影、补补片&#xff0c;是再正常不过的事。 电影嘛&#xff0c;要沉浸&#xff0c;…...

代码规范和架构【立芯理论一】(2025.06.08)

1、代码规范的目标 代码简洁精炼、美观&#xff0c;可持续性好高效率高复用&#xff0c;可移植性好高内聚&#xff0c;低耦合没有冗余规范性&#xff0c;代码有规可循&#xff0c;可以看出自己当时的思考过程特殊排版&#xff0c;特殊语法&#xff0c;特殊指令&#xff0c;必须…...

tomcat入门

1 tomcat 是什么 apache开发的web服务器可以为java web程序提供运行环境tomcat是一款高效&#xff0c;稳定&#xff0c;易于使用的web服务器tomcathttp服务器Servlet服务器 2 tomcat 目录介绍 -bin #存放tomcat的脚本 -conf #存放tomcat的配置文件 ---catalina.policy #to…...

ubuntu22.04 安装docker 和docker-compose

首先你要确保没有docker环境或者使用命令删掉docker sudo apt-get remove docker docker-engine docker.io containerd runc安装docker 更新软件环境 sudo apt update sudo apt upgrade下载docker依赖和GPG 密钥 # 依赖 apt-get install ca-certificates curl gnupg lsb-rel…...

macOS 终端智能代理检测

&#x1f9e0; 终端智能代理检测&#xff1a;自动判断是否需要设置代理访问 GitHub 在开发中&#xff0c;使用 GitHub 是非常常见的需求。但有时候我们会发现某些命令失败、插件无法更新&#xff0c;例如&#xff1a; fatal: unable to access https://github.com/ohmyzsh/oh…...