30no2's Blog.

千万级秒杀项目实战

字数统计: 1.5k阅读时长: 5 min
2019/11/13 Share

千万级秒杀项目实战

一、设计思路

1. 设计分析

  • 用户:量大,正常用户,恶意用户(数据清洗)
  • 地区:全国范围内各地区都要访问到(cdn加速)
  • 业务流程:前台(用户能看到的部分)后台(商家或者管理者使用)

2. 设计分层

  • 第一层:商品展示层(负责对应商品的展示)
  • 第二层:用户登记层(用户登记相关信息,秒杀准备)
  • 第三次:数据接入(将用户的信息接入到数据库或者处理层)
  • 第四层:数据处理层(接入层数据没有问题,存入处理层)

3. 导图

20191113-1.jpg

二、代码分析

1. 秒杀第一层(展示页面)

1)页面优化

  • 页面

  • 图片

  • css
  • js
  • 压缩

2)cnd网络加速

  • 阿里云cdn(推荐)–oss开放存储
  • 解决全国各地访问不均衡的问题
  • 内容刷新

3)隐藏跳转页面(重点)

  • 修改页面信息

    • 修改js
    • 修改页面
  • 双页面

    • 展示页面

      • 倒计时
        • 1、用服务器时间(推荐设置成东9区)
        • 2、考虑网络传输耗时(不是很明显,但是需要考虑)
        • 3、获取时间可以冲ajax响应头中获取(通过getResponsetHeader(“Date”)来获取,服务器不需要写时间生成脚本)
      • 倒计时实现方案
        • 1、原则:尽量减少服务器请求
        • 2、处理方式
          • 刷新就获取服务器时间,然后自己累加
          • 获取服务器时间
          • js实现递减效果
    • 购买页面

      1
      2
      3
      4
      5
      6
      7
      8
      //第一步--删除文件
      $file_path = 'a.txt';
      $f = file_exists($file_path)&&unlink($file_path);
      //第二部--生成自己需要的文件
      $file_path = 'b.html';
      $myfile = fopen($file_path,'w');
      $txt = "<h1>大家好</h1>";
      fwrite($myfile,$txt);

4)端口/最大连接数

  • 关闭没用的端口
  • 最大连接数设置
    • 内存
    • cpu
    • 默认150个设置512个

5)电脑性能监控

  • cpu
  • 内存
  • 网络
  • 硬盘
  • 版本推荐
    • php7
    • apache2.4
    • 推荐理由
      • 新品
      • 缺点:很多扩展不全
  • 服务器配置
    • 1、选择unbuntu 14.04
    • 2、安装ssh
    • 3、apt-get update
    • 4、tasksel install lmap-server

6)特点

  • 应对高并发/高可用(主要cnd–阿里是6台机器回源,所有我们只要抗住6台机器请求就可以了)

7)构想

  • 展示状态
    • 三种
      • 秒杀等待倒计时页面
        • 秒杀进行中、秒杀按钮可用状态
        • 秒杀结束提示页面
    • 技术难点
      • 秒杀等待页面与秒杀按钮可用状态页面,切换的时候,不至于让秒杀登记的地址提前曝光!
        • 方案:用linux定时任务crontab 执行shell脚本,进行文件的替换
  • 高并发/高可用
    • 技术关键点
      • 高可用
        • 双活
        • 云解析(推荐+负载均衡)
      • 高并发
        • 负载均衡
        • cdn加速
        • 单台调优
          • 最大连接数
          • 可靠性能
    • 结合当前页面的思考
      • 页面特点
        • 纯静态:html标签/css属性/js
        • 如果是纯静态:高并发–cnd加速

8)具体实施

  • 页面
    • 1.商品展示页
    • 2.商品秒杀进行中
    • 3.秒杀结束
  • 知识点
    • 切换
      • 1-2切换
        • a. linux cron定时任务
        • b. shell脚本知识
      • 2-3切换
        • .php文件
    • 秒杀倒计时
      • js实现
    • 服务器部署

2.秒杀第二层(用户登记)

1)目的

  • 登记用户信息
    • 简单的小白过滤
      • 肉鸡方案
      • 控制多台计算机同时抢
    • ajax数据发送
      • 手机号/验证码之类

2)知识点

  • 静态页面/服务器(同第一层)
  • 简单的数据验证
  • ajax跨域

3)代码实现

3.秒杀数据接入层

1)任务

  1. 数据校验

  2. 存入队列

  3. 检测订单商品数量

2)知识点

  1. 数据校验

    • ajax跨域安全
      • 数据源验证
    • 类似token数据校验
      • 加密算法(类似序列号)
  2. 队列

    • why——高并发流浪数据插入

      • 排队
        1. 微观角度 —— 其实从硬件IP可以排序!单一排序
        2. linux底层驱动,也是从缓存池中,获取数据
      • 去重
  • 如何选择

    • 多次任务存储
      1. 队列
        • 链表
        • 数组
      2. 堆栈
        • nosql
      3. memcache
        • 简单
        • php控制逻辑+memcache控制数据
        1. redis
      • php引擎
        • PRdies:纯php完成
          • phpredis:c扩展
          • 命令选择
        • 列表 ——无自动去重
        • 集合
          1. 快速
          2. 随机无序
        • 有序集合
          • 过期时间
          • mysql —— 消息队列插件
  • 代码实现

    • test_redis.php
      • 本地
      • 阿里
    • 效果展示——流程演示
    • 类封装——兼容本地以及远程的类封装
    • 最终效果封装——基于阿里
  1. 商品数量检测
  2. 关键点:
    • redis封装
    • 序列号生成

4.秒杀第四层

1)数据处理

  • 任务——转存nosql数据到mysql
  • 知识点——无

三、具体代码实现

1.第一层代码实现

1)关键点:

  • 倒计时:

    • css——背景图足够大,将倒计时固定

    • js

      • 倒计时js

      806-AAA95-DFE4-46-E7-82-DD-EF9-DD8-D70-F28-20191115094130.jpg

      • 根据剩余秒数显示时间

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        function getNewSyTime(sec){
        var s = sec % 60;
        sec = (sec - s)/60;//min
        var m - sec % 60;
        sec = (sec - m)/60;//hour
        var h = sec % 24;
        var d = (sec - h) / 24;//day
        var syTimeStr = "";
        if(d > 0){
        syTimeStr += d.toString() + "天";
        }
        syTimeStr = ("0"+h.toString()).substr(-2)+"时"
        +("0"+m.toString()).substr(-2)+"分"
        +("0"+s.toString()).substr(-2)+"秒;
        return syTimeStr;

        }
- 秒杀结束替换脚本

  1. 秒杀替换脚本

  
1
2
3
4
#!/user/bin/env bash
date>>/root/456.txt
rm -rf '/alidata/www/deault/index.html'
cp '/alidata/www/deault/index_sale.html' '/alidata/www/deault/index.html'
2. 服务器定时任务
1
0 12 * * * root /bin/51miao.sh
3. php代码实现
1
2
3
4
5
6
7
8
9
10
//第一步删除文件
$file_path = 'index.html';
$f = file_exists($file_path)&&unlink($file_path);
//第二步:生成自己需要的文件
$file_path = 'index.html';
$myfile = fopen($file_path,"w");
//获取文件内容
$file_path = 'index_over.html';
$txt = file_get_contents(file_path);
fwrite($myfile,$txt);

2.第二层

1)js

  • 对用户名手机号进行判断——value值
    • value值序列号加密
    • 正则手机号判断
    • jsonp发送后台验证通过,则登记记录

3.第三层

  • php
    • 创建token
    • 检验token
    • 给1,2,4层发送通知
    • redis插入数值
      • 插入数值 flag+1
    • 安全过滤

4.第四层

  • redis获取数据插入到mysql中

四、演示

CATALOG
  1. 1. 千万级秒杀项目实战
    1. 1.1. 一、设计思路
      1. 1.1.1. 1. 设计分析
      2. 1.1.2. 2. 设计分层
      3. 1.1.3. 3. 导图
    2. 1.2. 二、代码分析
      1. 1.2.1. 1. 秒杀第一层(展示页面)
        1. 1.2.1.1. 1)页面优化
        2. 1.2.1.2. 2)cnd网络加速
        3. 1.2.1.3. 3)隐藏跳转页面(重点)
        4. 1.2.1.4. 4)端口/最大连接数
        5. 1.2.1.5. 5)电脑性能监控
        6. 1.2.1.6. 6)特点
        7. 1.2.1.7. 7)构想
        8. 1.2.1.8. 8)具体实施
      2. 1.2.2. 2.秒杀第二层(用户登记)
        1. 1.2.2.1. 1)目的
        2. 1.2.2.2. 2)知识点
        3. 1.2.2.3. 3)代码实现
      3. 1.2.3. 3.秒杀数据接入层
        1. 1.2.3.1. 1)任务
        2. 1.2.3.2. 2)知识点
      4. 1.2.4. 4.秒杀第四层
        1. 1.2.4.1. 1)数据处理
    3. 1.3. 三、具体代码实现
      1. 1.3.1. 1.第一层代码实现
        1. 1.3.1.1. 1)关键点:
      2. 1.3.2. 2.第二层
        1. 1.3.2.1. 1)js
      3. 1.3.3. 3.第三层
      4. 1.3.4. 4.第四层
    4. 1.4. 四、演示