秒杀活动的设计

来自我的博客 秒杀活动的设计

业务的基本说明

  1. 运营评估最高的并发会达到 10W(根据推广的力度,以及以往的经验)
  2. 业务现有的服务器架构 反向代理 4台,前端机 8台, db 2台(主从),redis 2台(主从)如下是服务器架构图

clipboard.png

动静分离

html 等静态文件上CDN ,这方面压力不大
后台程序动态接口,必须支持高并发,用户体验必须作好
后端程序优化点(欢迎你们补充)php

  • 程序尽量的减小加载的文件
  • 程序减小没必要要的网络请求
  • redis 队列来做 异步方式实现
// 后台进程消费队列 我的使用brpoplpush方法 取出数据并用存入另外队列做数据备份
$block_expire_time = 0; # 设置阻塞等待时间为永久
$redis->brpoplpush($key, $backup_key, $block_expire_time);
  • redis 缓存
  • 前端点击按钮请求后变灰,防止用户重复点击
  • 静态文件上CDN
  • nginx的最大链接数设置为550,防止链接数过大时所有到php,致使php服务挂了
  • 针对每一个用户加并发锁(redis),防止高并发状况判断条件被绕过,程序执行完后解锁。
$lock_status = $redis->set($lock_key, 1, array("NX", "EX"=>$expire_time));

高并发下奖品超发问题

我的设计的方案:提早把每一个奖品放入 redis队列,每一个key一个奖品,队列的长度是奖品的数量,能够保证奖品不会超发放
另外,假设使用
悲观锁,在更新数据的时候加锁,其它的都为等待状态,不合适秒杀场景
乐观锁 基本是采用带版本号更新,版本号匹配才能更新,其它的回滚,虽然保证的数据的安全不超发放,可是在高并发场景下,DB只有两台的时候,超过mysql 进程堆积确定会的, 超过最大链接数是怎么办,一系列的问题须要解决,因此该方案不合适html

程序压测结果分析服务器能抗的并发

在平均响应时间300ms内,单台qps 750 左右(保持300ms是公司压测试的规范指标)
10台机器(后面新增2台到 8+2)一秒钟能处理: 10 * 750 = 7500
保守的并发只有7500,与10w 差距大,须要在执行方案上解决,公司不可无限的申请web机器。
解决10W并发问题(资源有限的状况)方案
在代理层作处理,根据权重挡掉93%的量,返回800(自定义),前端判断是否为800,是则提示火爆用户重试(对应的方案设置友好一些)前端

活动的序列图及说明

  1. 接口程序不链接查询mysql数据库
  2. 奖品的数据存放redis队列,每一个奖品一个key,队列长度是奖品的数量
  3. 用户成功领取红包(或抢购)时的代码流程(不包括业务限制与防刷),从队列获取奖品成功,再入队列(此队列后台消费入库),返回给用户领取成功。在用户体验上有所提高,但若是后台队列堆积太多,未能消费完成,用户查看的红包时是没有对应记录的,因此针对本身的需求做对应的优化。

clipboard.png

活动流程图(开爷画的)

clipboard.png

相关文章
相关标签/搜索