秒杀系统解决方案

感谢于霆霖的投稿,本文摘自:http://yutinglin.cn/2017/08/01/秒杀系统解决方案/

我看了二十篇左右的秒杀系统设计及解决方案的文章,从架构、产品、前端、后端四个层面分别总结了一些解决方案。

要点总结:

1.架构:扩容,业务分离,数据分离

2.产品:下单按钮控制,秒杀答题削峰,简化页面设计

3.前端:限流(反作弊) 静态化

4.后端:内存 队列

一、秒杀一般会带来2个问题:

1、高并发

比较火热的秒杀在线人数都是10w起的,如此之高的在线人数对于网站架构从前到后都是一种考验。

2、超卖

任何商品都会有数量上限,如何避免成功下订单买到商品的人数不超过商品数量的上限,这是每个抢购活动都要面临的难题。

实际上超卖问题是高并发带来的一个子问题,但是因为这个问题太过致命,所以我们把他的解决方案单独拿出来说。

二、如何解决?

1.架构层面:

秒杀架构设计原则:
  1. 尽量将请求拦截在系统上游
  2. 读多写少的常用多使用缓存
扩容

说白了加机器

系统隔离

为了避免短时间内的大访问量对现有网站业务造成的冲击,可以将秒杀系统独立部署。系统隔离更多是运行时的隔离,可以通过分组部署的方式和另外99%分开。秒杀还申请了单独的域名,目的也是让请求落到不同的集群中。即使秒杀系统崩溃了,也不会对网站造成影响。

数据隔离

将即将被秒杀的热数据维护到redis。秒杀所调用的数据大部分都是热数据,比如会启用单独cache集群或MySQL数据库来放热点数据,目前也是不想0.01%的数据影响另外99.99%。

减库存操作
一种是拍下减库存 另外一种是付款减库存;目前采用的“拍下减库存”的方式,拍下就是一瞬间的事,对用户体验会好些。

2.产品层面:

1.控制秒杀商品页面抢购按钮的可用/禁用。

购买按钮只有在秒杀开始的时候才能点亮,在此之前是灰色的,显示活动未开始。

2.增加了秒杀答题,基于时间分片削峰

秒杀答题一个很重要的目的是为了防止秒杀器。还有一个重要的功能,就是把峰值的下单请求给拉长了,从以前的1s之内延长到2~10s左右,请求峰值基于时间分片了,这个时间的分片对服务端处理并发非常重要,会减轻很大压力,另外由于请求的先后,靠后的请求自然也没有库存了,也根本到不了最后的下单步骤,所以真正的并发写就非常有限了。其实这种设计思路目前也非常普遍,如支付宝的“咻一咻”已及微信的摇一摇。

3.秒杀页面设计简化:

秒杀场景业务需求与一般购物不同,用户更在意的是能够抢到商品而不是用户体验。所以秒杀商品页面应尽可能简单并且拍下后地址等个人信息应该使用默认信息,减轻秒杀进行时系统负载,若有更改可以在秒杀结束后进行更改。

3.前端层面

静态化以及页面缓存

将页面能够静态的部分都静态化,并将静态页面缓存于CDN,以及反向代理服务器,可能还要临时租借服务器。 利用 页面静态化、数据静态化,反向代理 等方法可以避免 带宽和sql压力 ,但是随之而来一个问题,页面抢单按钮也不会刷新了,可以把 js 文件单独放在js服务器上,由另外一台服务器写 定时任务 来控制js 推送。 另外还有一个问题,js文件会被大部分浏览器缓存,我们可以使用xxx.js?v=随机数 的方式来避免js被缓存。

限流(反作弊)

1.针对同一个用户id来实现,前端js控制一个客户端几秒之内只能发送同一个请求,后端校验同一个uid在几秒之内返回同一个页面

2.针对同一个ip来实现,进行ip检测,同一个ip几秒之内不发送请求或者只返回同一个页面

3.针对多用户多ip来实现,依靠数据分析

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

4.后端层面:

1.加入缓存redis:

因为秒杀是典型的读多写少的场景,适合操作内存而非操作硬盘;缓存工具redis本身的操作是保证原子性的,所以可以保证请求了redis的写的操作的线程安全性。

2.加入消息队列,利用队列进行削峰:

将用户请求放置于一个或多个队列中,队列中元素总和等于该商品库存总和,未进入队列的请求均失败。利用多线程轮询分别从一个或多个队列中取出用户请求。操作redis进行减库存操作,成功减库存之后返回成功,并将用户信息与商品信息存入另一个队列当中,进行生成订单的操作。利用两个队列异步处理业务减轻秒杀高峰时期服务器负载。

3.程序计数器:

队列与缓存为了保证请求redis的次数不超过总的库存量,利用一个程序计数器来这一点。程序计数器用JUC包下原子类可以实现。

4.分布式锁

分布式情况下可以利用分布式锁来解决任务每次只能由一次服务来执行且不能重复执行。 分布式锁的实现:zk、redis 分布式锁的优化:先考虑是否可以去锁,然后考虑尽可能多用乐观锁,少用悲观锁。这里有一个问题,乐观锁如果每一次都会有并发冲突的话性能反而不如悲观锁,那么难道真的多用乐观锁性能会比悲观锁高吗?选举考虑ha,比如心跳检测。

5.分布式去锁 方案

利用集群并发加入队列,选举队列处理服务单点执行,这样可以保证并发实现和加锁一样的并发量但不会影响性能。

原文发布于微信公众号 - 程序猿DD(didispace)

原文发表时间:2017-09-12

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏腾讯移动品质中心TMQ的专栏

Windows开机过程和测试方法探索

用户会经常抱怨自从安装自己的应用后,电脑开机变慢,到底是系统的原因还是应用的原因,为了了解这里的问题,探秘了下windows的开机过程和测试方法。 一、开机过...

28710
来自专栏分布式系统进阶

KafkaBridge - Kafka Client SDK 开源啦~~~

KafkaBridge 封装了对Kafka集群的读写操作,接口极少,简单易用,稳定可靠,支持c++/c、php、python、golang等多种语言,并特别针对...

901
来自专栏Timhbw博客

Windows下iOS开发环境搭建教程

2016-06-1513:59:42 发表评论 2,027℃热度 1.下载工具 2.安装基本文件 3.开始主要步骤 4.总结 目录 可能许多初学者并没...

1.2K8
来自专栏迁移服务平台

腾讯云文件迁移使用指南

迁移上云的时候,会有迁移上腾讯云对象存储(cos)的需求,目前的迁移方案有两种:1、cos提供的COS Migration工具;2、客户自己利用友商和cos的a...

3924
来自专栏java一日一条

Java EE7和Maven工程入门(1)

在日常工作中,我经常需要解决许多简单的或者是复杂的Maven/Java EE工程结构的问题。为了找到解决办法,我经常要拿项目的结构做实验,在不同应用服务器上对部...

491
来自专栏无题

秒杀系统解决方案

从架构、产品、前端、后端四个层面针对秒杀场景(可以扩展到所有高并发场景)分别总结了一些解决方案。 要点总结: 1.架构:扩容,业务分离,数据分离 2.产品:下...

4714
来自专栏FreeBuf

开发者误读芯片厂商调试文档,导致主要操作系统均出现新内核漏洞

美国计算机安全应急响应中心(以下简称“CERT”)日前发布公告称,Windows、macOS、Red Hat、Ubuntu、SUSE Linux、FreeBSD...

1165
来自专栏纯洁的微笑

再有人问你分布式事务,把这篇扔给他

不知道你是否遇到过这样的情况,去小卖铺买东西,付了钱,但是店主因为处理了一些其他事,居然忘记你付了钱,又叫你重新付。又或者在网上购物明明已经扣款,但是却告诉我没...

3431
来自专栏IT大咖说

VMware vSphere 6.7 新功能介绍

内容来源:2018 年 06 月 19 日,VMware大中华区原厂高级技术讲师姚泉在“VMware在线技术专题分享·第二期”进行《VMware vSphere...

5373
来自专栏程序你好

.Net桌面系统架构设计

1321

扫码关注云+社区

领取腾讯云代金券