一、核心思想:
网站秒杀时的并发比正常运营时多的多,所以网站的秒杀业务不能使用正常的网站业务流程,也不能和正常的网站交易业务共用服务器(否则造成巨大浪费),必须设计部署专门的秒杀系统,进行专门应对
二、技术挑战:
1.对现有网站业务造成冲击:秒杀活动只是网站营销的一个附加活动,具有时间短,高并发的特点,如果和网站原有应用部署在一起,必然会对现有业务造成冲击,稍有不慎可能导致整个网站瘫痪
2.高并发下的应用、数据库负载:用户在秒杀开始前,通过不停刷新页面以保证不错过秒杀,这些请求按照一般的网站应用架构,访问应用服务器、连接数据库,会对应用服务器和数据库服务器造成极大的负载压力
3.突然增加的网络及服务器带宽:假设商品页面大小200K,最大并发请求数是10000,则需要网络和服务器带宽是2G(200K*10000),这些网络带宽是因为秒杀活动新增的,超过网站平时使用的带宽
4.直接下单:下单页面也是一个普通URL,要防止用户在秒杀开始前访问这个URL(下单)
三、应对策略:
1.秒杀系统独立部署:避免高并发拖垮整个网站,还可使用独立域名使其与网站完全隔离,即使秒杀系统崩溃也不对网站造成任何影响
2.秒杀商品页面静态化:秒杀商品页面不使用网站原本的商品详情页面,页面内容静态化,将商品描述、商品参数、成交记录和用户评价全部写入一个静态页面,用户请求不需要经过应用服务器的业务逻辑处理,也不需访问数据库。所以秒杀商品服务不需要部署动态的Web服务器和数据库服务器
3.租借秒杀活动网络带宽:秒杀新增的网络带宽,必须和运营商重新购买或租借。为减轻网站服务器压力,需要将秒杀商品页面缓存在CDN,同样需要和CDN服务商临时租借新增的出口带宽
4.动态生成随机下单页面URL:避免用户直接访问下单页面URL,在下单页面URL加入由服务器端生成的随机数作为参数,在秒杀开始的时候才能得到,即使秒杀系统的开发者也无法在秒杀开始前访问下单页面的URL。
四、秒杀系统架构设计:
1.页面设计尽可能简单(用户更关心如何快速刷新进入下单页面,而不是商品详情等用户体验细节):
①购买按钮在秒杀活动开始时才变亮,在此之前都置灰,不可点 ②下单表单也尽可能简单:1️⃣购买数量只能是一个且不可更改 2️⃣送货地址和付款方式都使用用户默认设置,没有默认也可不填,允许等订单提交后修改(商品页面是静态的,下单页面还是动态的) 3️⃣只有第一个提交的订单发送给网站的订单子系统,其余用户提交订单后只能看到秒杀结束页面
具体实现:
①购买按钮如何控制:由于商品页面静态化(可能缓存在CDN、反向代理甚至用户浏览器,秒杀开始时用户刷新页面请求不会到达应用服务器,所以按钮不能动态生成),
解决办法是用JS控制,在秒杀页面加入一个JS文件引用,该JS文件加入 秒杀是否开始标识 和 下单页面的URL的随机参数,当秒杀开始时生成新的一个JS文件并被用户浏览器加载,控制秒杀商品页面的展示。这个JS文件使用随机版本号,并且不被浏览器、CDN和反向代理服务器缓存。如下图所示:
这个JS文件非常小,即使每次浏览器刷新访问JS文件服务器也不会对服务器集群和网络带宽造成太大压力。
②如何只允许第一个提交的订单被发送到订单子系统:
1️⃣在用户提交订单时,检查是否已经有订单提交 2️⃣为减轻服务器负载压力,可以控制进入下单页面的入口,只有少数用户能进入下单页面,其他用户直接进入秒杀结束页面(下图为假设下单服务器集群有10台服务器,每台服务器只接受最多10个下单请求)
秒杀系统的整体架构如下:
小结:
在遵循秒杀活动游戏规则的基础上,保持适度的公平公正即可。即使系统出了故障,也不应该给用户显示出错界面,而是显示秒杀活动结束页面,避免不必要的困扰。
后续还有一篇关于性能优化设计的笔记,几乎也都可以用于秒杀系统的优化。