当前位置: 首页 > 编程日记 > 正文

秒杀系统架构设计

秒杀活动的技术挑战

1. 对现有网站业务造成冲击

秒杀活动只是网站营销的一个附加活动,这个活动具有时间短,并发访问量大的特点,如果和网站原有应用部署在一起,必须会对现有业务造成冲击,稍有不慎可能导致整个网站瘫痪。

2. 高并发下的应用、数据库负载

用户在秒杀开始前,通过不停刷新浏览器页面以保证不会错过秒杀,这些请求如果按照一般的网站应用架构,访问应用服务器、连接数据库,会对应用服务器和数据库服务器造成极大的负载压力。

3. 突然增加的网络及服务器带宽

假设商品页面大小200K(主要是商品图片大小),那么需要的网络和服务器带宽是2G(200K×10000),这些网络带宽是因为秒杀活动新增的,超过网站平时使用的带宽。

4. 直接下单

秒杀的游戏规则是到了秒杀时间才能开始对商品下单购买,在此时间点之前,只能浏览商品信息,不能下单。而下单页面也只是一个普通的URL,如果得到这个URL,不用等到秒杀开始就可以下单了。

秒杀系统的应对策略

1. 秒杀系统独立部署

为了避免因为秒杀活动的高并发访问而拖垮整个网站,使整个网站不必面对蜂拥而来的用户访问,可将秒杀系统独立部署;如果需要,还可以使用独立的域名,使其与网站完全隔离,即使秒杀系统崩溃了,也不会对网站造成任何影响。

2. 秒杀商品页面静态化

重新设计秒杀商品页面,不使用网站原来的商品详情页面,页面内容静态化:将商品描述、商品参数、成交记录和用户评价全部写入一个静态页面,用户请求不需要经过应用服务器的业务逻辑处理,也不需要访问数据库。所以秒杀商品服务不需要部署动态的Web服务器和数据库服务器。

3. 租借秒杀活动网络带宽

因为秒杀新增的网络带宽,必须和运营商重新购买或者租借。为了减轻网站服务器的压力,需要将秒杀商品页面缓存在CDN,同样需要和CDN服务商临时租借新增的出口带宽。

4. 动态生成随机下单页面URL

为了避免用户直接访问下单页面URL,需要将该URL动态化,即使秒杀系统的开发者也无法在秒杀开始前访问下单页面的URL。办法是在下单页面URL加入由服务器端生成的随机数作为参数,在秒杀开始的时候才能得到。

秒杀系统架构设计

秒杀系统为秒杀而设计,不同于一般的网购行为,参与秒杀活动的用户更关心的是如何能快速刷新商品页面,在秒杀开始的时候抢先进入下单页面,而不是商品详情等用户体验细节,因此秒杀系统的页面设计应尽可能简单。

商品页面中的购买按钮只有在秒杀活动开始的时候才变亮,在此之前及秒杀商品卖出后,该按钮都是灰色的,不可以点击。

下单表单也尽可能简单,购买数量只能是一个且不可以修改,送货地址和付款方式都使用用户默认设置,没有默认也可以不填,允许等订单提交后修改;只有第一个提交的订单发送给网站的订单子系统,其余用户提交订单后只能看到秒杀结束页面。

除了上面提到的秒杀系统的技术挑战及应对策略,还有一些其他问题需要处理。

1. 如何控制秒杀商品页面购买按钮的点亮

购买按钮只有在秒杀开始的时候才能点亮,在此之前是灰色的。如果该页面是动态生成的,当然可以在服务器端构造响应页面输出,控制该按钮是灰色还 是点亮,但是为了减轻服务器端负载压力,更好地利用CDN、反向代理等性能优化手段,该页面被设计为静态页面,缓存在CDN、反向代理服务器上,甚至用户 浏览器上。秒杀开始时,用户刷新页面,请求根本不会到达应用服务器。

解决办法是使用JavaScript脚本控制,在秒杀商品静态页面中加入一个JavaScript文件引用,该JavaScript文件中包含 秒杀开始标志为否;当秒杀开始的时候生成一个新的JavaScript文件(文件名保持不变,只是内容不一样),更新秒杀开始标志为是,加入下单页面的 URL及随机数参数(这个随机数只会产生一个,即所有人看到的URL都是同一个,服务器端可以用redis这种分布式缓存服务器来保存随机数),并被用户 浏览器加载,控制秒杀商品页面的展示。这个JavaScript文件的加载可以加上随机版本号(例如xx.js?v=32353823),这样就不会被浏 览器、CDN和反向代理服务器缓存。

这个JavaScript文件非常小,即使每次浏览器刷新都访问JavaScript文件服务器也不会对服务器集群和网络带宽造成太大压力。

2. 如何只允许第一个提交的订单被发送到订单子系统

由于最终能够成功秒杀到商品的用户只有一个,因此需要在用户提交订单时,检查是否已经有订单提交。如果已经有订单提交成功,则需要更新 JavaScript文件,更新秒杀开始标志为否,购买按钮变灰。事实上,由于最终能够成功提交订单的用户只有一个,为了减轻下单页面服务器的负载压力, 可以控制进入下单页面的入口,只有少数用户能进入下单页面,其他用户直接进入秒杀结束页面。假设下单服务器集群有10台服务器,每台服务器只接受最多10 个下单请求。在还没有人提交订单成功之前,如果一台服务器已经有十单了,而有的一单都没处理,可能出现的用户体验不佳的场景是用户第一次点击购买按钮进入 已结束页面,再刷新一下页面,有可能被一单都没有处理的服务器处理,进入了填写订单的页面,可以考虑通过cookie的方式来应对,符合一致性原则。当然 可以采用最少连接的负载均衡算法,出现上述情况的概率大大降低。

小结

秒杀是对网站架构的极大考验,在难以预计和控制的高并发访问的冲击下,稍有不慎,系统就会被用户秒杀,导致整个系统宕机,活动失败,构成重大事故。因此在 遵循秒杀活动游戏规则的基础上,为了保证系统的安全,保持适度的公平公正即可。即使系统出了故障,也不应该给用户显示出错页面,而是显示秒杀活动结束页 面,避免不必要的困扰。

摘自《大型网站技术架构:核心原理与案例分析》 李智慧  豆瓣读书

相关文章:

SpringBoot 2.x 使用 JWT(JSON Web Token)

一、跨域认证遇到的问题 由于多终端的出现,很多的站点通过 web api restful 的形式对外提供服务,采用了前后端分离模式进行开发,因而在身份验证的方式上可能与传统的基于 cookie 的 Session Id 的做法有所不同,除了面临跨域提交 c…

在Unity中制作4种不同的游戏

流派:电子学习| MP4 |视频:h264,1280720 |音频:AAC,48.0 KHz 语言:英语中英文字幕(根据原英文字幕机译更准确)|大小解压后:8.6 GB 含课程素材 |时长:15h 3m Unity 制作4款无代码手机游戏 Make 4 games in Unity with …

Spring学习笔记:1(初步认识概念)

Spring的三大主要特征 spring主要特征有三个:控制反转(IOC),依赖注入(DI)和面向切面(AOP)。 IoC:Inverse of Control(控制反转) 1.对控制反转的…

shell example01

条件判断 if [[ -e ${1} ]]; thenecho "$(tput setaf 2) found ${1} $(tput sgr0)"cat ${1} elseecho "$(tput setaf 1) not found ${1} $(tput sgr0)"exit 1 fi//简化[[ -e ${1} && -e ${2} ]] && cat ${1} > ${2}//判断取反txt4.txti…

gradle教程 [原创](eclipse/ADT下 非插件 非Android Studio/AS)纯手打 第一篇:安装配置gradle...

一个bug 一个脚印的叫你们用gradle。 1介于网络上的很多资料都是老的 不适用与现在的新版本gradle 尤其是有些gradle方法改名了老的用不了 2介于网上都是粘贴复制并且零碎我很蛋疼啊,走了很多歪路才弄出来,所以我弄一个完全完整的版本 3我不但会写gradle…

java的static关键字

java的static关键字 静态变量和静态方法 static关键字最基本的用法是: 1、被static修饰的变量属于类变量,可以通过类名.变量名直接引用,而不需要new出一个类来 2、被static修饰的方法属于类方法,可以通过类名.方法名直接引用&…

Spring学习笔记:2(IOC装配Bean之xml方式)

xml配置方式装配Bean 本文借鉴于:https://www.cnblogs.com/qdhxhz/p/6511887.html Spring框架Bean实例化的方式提供了三种方式实例化Bean 构造方法实例化(默认无参数,用的最多)静态工厂实例化实例工厂实例化 代码如下: Bean1类(构造方法…

学习RPG Maker MZ开发创建并发布PC和移动端游戏

Complete RPG Maker MZ: Create and Publish for PC and Mobile 完整的RPG制造商MZ:为个人电脑和移动设备创建和发布 MP4 |视频:h264,1280720 |音频:AAC,44.1 KHz,2 Ch 语言:英语中英文字幕(根据原英文字幕机译更准确…

CSS选择器总结

总结几种自己比较容易混淆的: 1. 后代选择器,写法是 E1 E2,如 ul li,选择的是所有后代,包括子后代、孙后代…; 2. 子选择器,写法 E1 > E2,只选择子后代,不包括孙后代元素&#xf…

OSChina 周六乱弹 —— 小明和网关超经典的故事~

2019独角兽企业重金招聘Python工程师标准>>> 周六,又到了瞎扯淡的时间了。周末,约会,男男女女,还有那啥那啥,你们懂得~ 男人和女人明显不同,这样才导致了异性相吸吗? 1. …

概念艺术绘画学习教程 Schoolism – Foolproof Concept Painting with Airi Pan

Schoolism——万无一失的概念绘画潘 大小解压后:3.19G 含课程素材文件 1920X1080 .mp4 语言:英语中英文字幕(根据原英文字幕机译更准确) 信息: 万无一失的概念绘画潘 本课程由概念设计师兼插画师潘开发,与大家分享她…

Mybatis复习笔记:1

关于模糊查找 模糊查找其实有两种基本操作(之前学的时候看的不太仔细&#xff0c;漏了…) 第一种 <select id"findByType" parameterType"String" resultType"com.domain.User">select * from product where product_type like #{produ…

文件只能安装一次

1 def get_mac_address(): 2 macuuid.UUID(int uuid.getnode()).hex[-12:] 3 return ":".join([mac[e:e2] for e in range(0,11,2)]) 获取计算机名字 1 import socket 2 socket.gethostname() linux下获取主机外网ip 1 import socket2 import fcntl3 impo…

Linux pipe函数

1. 函数说明 pipe&#xff08;建立管道&#xff09;&#xff1a; 1) 头文件 #include<unistd.h> 2) 定义函数&#xff1a; int pipe(int filedes[2]); 3) 函数说明&#xff1a; pipe()会建立管道&#xff0c;并将文件描写叙述词由參数filedes数组返回。 fi…

操作系统知识点:全面

操作系统知识点&#xff1a;全面 https://www.jianshu.com/p/c3a3cc0254b1 https://www.jianshu.com/u/881ef7b85f62 posted on 2019-09-03 21:44 竹径风声 阅读(...) 评论(...) 编辑 收藏 转载于:https://www.cnblogs.com/girl1314/p/11455906.html

在UE4中创建CG动画 How to create a movie in Unreal Engine 4 using Metahuman

MP4 |视频:h264&#xff0c;1280720 |音频:AAC&#xff0c;44.1 KHz 语言&#xff1a;英语中英文字幕&#xff08;根据原英文字幕机译更准确&#xff09;|大小解压后:1.55 GB |时长:1h 16m 你会学到什么 如何在虚幻引擎4中创建CG动画 虚幻引擎4 Metahuman 使用metahuman在虚幻引…

MyBatis复习笔记2:配置文件详解

配置文件详解 属性&#xff08;properties&#xff09; MyBatis可以使用 properties 来引入外部 properties 配置文件的内容 resource&#xff1a;引入类路径下的资源 url&#xff1a;引入网络路径或者磁盘路径下的资源 properties 有三种方式使用&#xff1a; 1、通过 reso…

Android ActionBarDrawerToggle、DrawerLayout、ActionBar 结合

ActionBarDrawerToggle是一个开关。用于打开/关闭DrawerLayout抽屉 ActionBarDrawerToggle 提供了一个方便的方式来配合DrawerLayout和ActionBar。以实现推荐的抽屉功能。 即点击ActionBar的homebutton&#xff0c;就可以弹出DrawerLayout抽屉。 在Activity中的两个回调函数中使…

【转】statfs获得硬盘使用情况 模拟linux命令 df

原文网址&#xff1a;http://blog.csdn.net/mociml/article/details/5335474 说明&#xff1a;本文以主要为转载内容&#xff0c;同时加入了我在使用过程中遇到问题对其的修正&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff0…

SQL常见的面试题

SQL常见的面试题 https://www.jianshu.com/p/558f2113bb62 posted on 2019-09-03 21:55 竹径风声 阅读(...) 评论(...) 编辑 收藏 转载于:https://www.cnblogs.com/girl1314/p/11455959.html

Mybatis入门:4(多表查询操作)

多表查询操作 Mybatis的多表操作 表之间的关系有几种&#xff1a;一对多、一对一、多对一、多对多 举例: 用户和订单就是一对多——一个用户可以下多个订单 订单和用户就是多对一——多个订单属于同一个用户 人和身份证号就是一对一 一个人只能有一个身份证号 一个身份证号只…

Python for虚幻引擎编辑器工具脚本学习教程

Python for Unreal Engine Editor Tools Scripting MP4 |视频:h264&#xff0c;1280720 |音频:AAC&#xff0c;44.1 KHz&#xff0c;2 Ch 语言&#xff1a;英语中英文字幕&#xff08;根据原英文字幕机译更准确&#xff09; |时长:23节课(4h 8m) |大小解压后:2.7 GB 含课程文件…

C++ Windows进程管理

功能&#xff1a; 1.各个进程启动、挂起、恢复、停止等 2.监听进程的运行状态&#xff0c;进程退出&#xff08;正常、非正常&#xff09;时&#xff0c;通知用户 3.异步队列 4.线程安全 进程管理器类&#xff1a; #ifndef __ProcessManager_ProcessManager_H__ #define __Proc…

shell中和||的使用方法

&&运算符:command1 && command2&&左边的命令&#xff08;命令1&#xff09;返回真(即返回0&#xff0c;成功被执行&#xff09;后&#xff0c;&&右边的命令&#xff08;命令2&#xff09;才能够被执行&#xff1b;换句话说&#xff0c;“如果…

SQL中内连接、外连接、交叉连接

SQL中内连接、外连接、交叉连接 SQL连接可以分为内连接、外连接、交叉连接。 数据库数据&#xff1a; book表 stu表 1.内连接 1.1.等值连接&#xff1a;在连接条件中使用等于号()运算符比较被连接列的列值&#xff0c;其查询结果中列…

Blender从头开始装配和动画制作低多边形风格的FPS手臂

Rigging and Animating Low Poly FPS Arms in Blender MP4 |视频:h264&#xff0c;1280720 |音频:AAC&#xff0c;44.1 KHz&#xff0c;2 Ch 语言&#xff1a;英语中英文字幕&#xff08;根据原英文字幕机译更准确&#xff09; |时长:21节课(4h 56m) |大小解压后:3.16 GB 含课程…

Mybatis复习笔记3:映射文件详解

映射文件详解 参数处理&#xff08;#和$的区别&#xff09; #{}&#xff1a;可以获取map中的值或者实体对象属性的值&#xff1b;${}&#xff1a;可以获取map中的值或者实体对象属性的值&#xff1b; select * from person where id${id} and name#{name} # 控制台输出&…

TMS320F28335项目开发记录2_CCS与JTAG仿真器连接问题汇总

CCS与仿真器连接问题 实际使用过程中。仿真器和CCS连接可能出现这样或那样的问题&#xff0c;或许你的连接非常成功&#xff0c;没碰到过什么问题。但我的问题的确不少&#xff0c;可能与电脑配置有关吧&#xff0c;也可能与人品有关吧。 以下的自己的一些错误和解决方法总…

Mysql备份与还原及优化方法

Mysql备份一般采用mysqldump命令&#xff0c;命令形式一般如下&#xff1a;$ mysqldump –hhostname –uuser –ppassword–Pport db_name > db_name.sql默认情况下&#xff0c;不备份存储过程和函数&#xff0c;若要备份存储过程和函数&#xff0c;要加上-R选项&#xff0c…

HashTable和HashMap的区别详解

HashTable和HashMap的区别详解 一、HashMap简介 HashMap是基于哈希表实现的&#xff0c;每一个元素是一个key-value对&#xff0c;其内部通过单链表解决冲突问题&#xff0c;容量不足&#xff08;超过了阀值&#xff09;时&#xff0c;同样会自动增长。 HashMap是非线程安全的&…