如何设计一个秒杀系统?

如何从整体角度,去设计一个秒杀系统。秒杀系统主要有这几个特征:

  • 瞬时间的流量特别高。过了秒杀的时间,流量就会瞬时结束

  • 大批量用户同时请求极少数商品

  • 在秒杀时间前,可能会有很多请求过来。比如在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限流。

9. 服务降级

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/701289.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

后继者00

题目链接 后继者 题目描述 注意点 题目中的树是二叉搜索树节点p在二叉搜索树中一定存在 解答思路 本题关键是找到值大于节点p的值的第一个节点,因为本题中的树是二叉搜索树,所以左子树的值始终小于根节点,右子树的值始终大于根节点访问到…

导入导出带下拉框模版(EasyExcel)

前言 项目进行到新的一个迭代了,赶了1周需求,接口终于处理完了。分享记录下迭代中处理导入、导出、下载模版功能的细节吧。 一、场景 EasyExcel(阿里)实现Excel数据处理三层表头,第二、三层表头动态数据根据第二、三层…

【技术】MySQL 8.4 免安装版配置

MySQL 8.4 免安装版配置 官网下载压缩包解压文件创建配置文件初始化数据库安装MySQL服务链接数据库修改密码 官网下载压缩包 从MySQL官网下载压缩包,官网:https://www.mysql.com/ 头部菜单点击【DOWNLOADS】,跳转到下载页面。在页面底部点击…

【FreeRTOS】内存管理笔记

一、为什么要自己实现内存管理? 后续的章节涉及这些内核对象:task、queue、semaphores和event group等。为了让FreeRTOS更容 易使用,这些内核对象一般都是动态分配:用到时分配,不使用时释放。使用内存的动态管理功能&…

unity 简易异步socket

1.unity 同步socket 改异步 using System.Collections; using System.Collections.Generic; using UnityEngine; using System.Net.Sockets; using UnityEngine.UI; using System.Threading; using System;public class Echo : MonoBehaviour {//定义套接字Socket socket;//UG…

Pikachu靶场--暴力破解

实验前的准备 问题解决 PHPStudy(小皮)V8.1安装后启动Apache报错AH00526: Syntax error 【数据库连接问题】【靶场访问错误】 抓不到本地靶场包的原因及解决方法_pakachu抓不到包 设置代理 BP添加和选择代理 火狐浏览器-->设置-->拓展-->搜索…

vue input 限制输入,小数点后保留两位 以及 图片垂直居中显示 和 分享 git 小技巧

&#xff08;1&#xff09;input 限制输入&#xff0c;小数点后保留两位 <template><div><el-input v-model"number" input"checkNumber" blur"completeNumber" placeholder"请输入"></el-input></div>…

【制作100个unity游戏之27】使用unity复刻经典游戏《植物大战僵尸》,制作属于自己的植物大战僵尸随机版和杂交版10(附带项目源码)

最终效果 系列导航 文章目录 最终效果系列导航前言使用DoTween优化阳光生成和拾取效果拾取阳光优化生成阳光优化 场景加载进度条新增加载场景Loading&#xff0c;绘制开始界面绘制菜单界面滑动滚轮一直滚动 场景加载源码结束语 前言 本节主要实现使用DoTween优化阳光生成和拾取…

域策略笔记

域策略 导航 文章目录 域策略导航一、设置客户端壁纸二、重定向用户配置文件路径三、部署网络打印机四、部署共享文件夹为网络驱动器五、通过域策略推送软件安装六、通过域策略限制软件的使用通过路径进行限制通过进程限制 七、通过域策略将文件添加白名单八、通过域策略添加可…

Python机器学习决策树可视化工具库之pybaobabdt使用详解

概要 决策树是一种常用的机器学习算法,广泛应用于分类和回归任务。为了更好地理解和解释决策树模型的决策过程,pybaobabdt 库提供了一种可视化工具,帮助用户以图形化方式展示决策树的结构和决策路径。本文将详细介绍 pybaobabdt 库,包括其安装方法、主要特性、基本和高级功…

5位AI界“考生”参加高考作文写作,最高分竟然是...

随着一年一度高考的帷幕缓缓降下&#xff0c;如同往昔&#xff0c;各省高考作文命题迅速成为了社会各界热议的焦点。高考作文命题历来紧扣时代脉搏&#xff0c;而今年新课标I卷则直接聚焦于当前最为炙手可热的领域——“人工智能”。 阅读下面的材料&#xff0c;根据要求写作。…

python __init__.py 文件案例练习

通过一些案例练习来更好地理解 __init__.py 的用法。我们将创建一个简单的 Python 包,并在 __init__.py 中实现不同的功能。 案例一:基本包结构 创建包目录结构: mypackage/__init__.pymodule1.pymodule2.py实现 module1.py 和 module2.py: # mypackage/module1.py def fu…

vue-editor设置字体font-family

背景&#xff1a;Vue项目中需要用到富文本编辑器&#xff0c;所以选择了vue-editor这个富文本编辑器&#xff0c;发现字体font-family只有三种Sans Serif、Serif、MonoSpace可以选择&#xff0c;满足不了产品的需求&#xff0c;所以用想要定义成常用字体&#xff0c;主要是需要…

SwiftUI 利用 Swizz 黑魔法为系统创建的默认对象插入新协议方法(六)

功能需求 在 SwiftUI 的开发中,我们往往需要借助底层 UIKit 的“上帝之手”来进一步实现额外的定制功能。比如,在可拖放(Dragable)SwiftUI 的实现中,会缺失拖放取消的回调方法让我们这些秃头码农们“欲哭无泪” 如上图所示,我们在拖放取消时将界面中的一切改变都恢复如初…

【unity笔记】二、海洋系统Crest Ocean System基础

1. 创建海平面 首先确定项目中导入了HDRP插件。这里使用Crest Ocean System HDRP插件。 在场景下创建空对象&#xff0c;这里命名为Ocean。将 OceanRenderer 组件分配给Ocean。该组件将生成海洋几何图形并执行所有必需的初始化。其中Global Wind Speed 属性可以调节风浪大小。…

【新品上架】动捕级视觉定位精度!!首款搭载 VIOBOT 模块的无人机发布!

P450_Viobot无人机是P450系列科研无人机的最新产品&#xff0c;硬件上采用VIOBOT定位模块&#xff0c;室内定位精度极高&#xff0c;静态定位精度可达到与动捕定位相当的厘米级定位&#xff0c;飞行悬停定位误差在3.5cm内。也可室外GPS飞行&#xff08;可选装RTK&#xff09;&a…

latex导入图片报错

忘记导包了 \usepackage{graphicx}其中Photo是图片名字 \begin{figure}\centering\includegraphics[width0.5\linewidth]{Photo.png}\caption{Enter Caption}\label{fig:enter-label} \end{figure}

基于STM32移植U8g2图形库——OLED显示(HAL库)

文章目录 一、U8g2简介1、特点2、U8g2的使用步骤 二、I2C相关介绍1、I2C的基本原理2、I2C的时序协议 三、OLED屏的工作原理四、汉字点阵显示原理五、建立STM32CubeMX工程六、U8g2移植1、U8g2源码2、移植过程 七、代码编写1、参考博主实现的U82G的demo例程&#xff08;1&#xf…

Matlab进阶绘图第59期—棒棒糖图

​棒棒糖图本质上是柱状图的一种变体。 棒棒糖图通过在每根柱子顶端添加圆点&#xff0c;以表示数据之间的相对位置。 此外&#xff0c;一般还会对每根棒棒糖按数值大小进行排序&#xff0c;从而更加方便阅读。 本文利用自制的Lollipop工具进行棒棒糖图的绘制&#xff0c;先…

python数据分析--- ch1-2 python初识入门

python数据分析--- ch1-2 python初识入门 1. 安装并启动jupyter2. 打印变量print()练一练 3. 变量与赋值 input()3.1 示例--饮料交换3.2 饮料交换完整code3.3 jupyter中写入code到py文件中3.4 在终端运行.py文件 &#xff1a; python 文件名3.5练一练1&#xff1a;简易版2&…