大型PHP电商网站商品秒杀功能实现思路分析

PHP技术
475
0
0
2022-10-15
标签   PHP高并发

项目背景介绍

  1. 关键点
  • 高可用:双活
  • 高并发:负载均衡、安全过滤
  1. 设计思路
  • 静态页面:cdn、网址隐藏、页面压缩、缓存机制
  • 动态页面:排队、异步、资质抢购
  1. 其他建议
  • 百度的建议:opcode缓存、cdn、更大的服务器实例
  • 阿里的建议:云监控、云盾、ecs、oss、rds、cdn

秒杀项目架构分析

  1. 认清当前的环境、形式
  • 用户:超大量、正常/坏人
  • 地域:全国各地
  • 业务流程:[前台]商品展示、登记、[后台]数据接入、数据处理

Laravel

技术实现要点分析

商品展示层

页面状态
  • 商品展示:秒杀倒计时页面
  • 秒杀进行中:点击进入秒杀页面
  • 秒杀活动结束:提示活动已结束

Laravel

用户登记层

页面状态
  • 秒杀进行中:秒杀登记页面
  • 秒杀结束了:秒杀结束页面

Laravel

数据接入层

页面功能
  • 数据校验:完成对数据、用户验证
  • 存入nosql队列:去重复、排序数据
  • 检测商品最大数量:提示活动已结束

Laravel

数据处理层

页面功能
  • 数据持久化:转存nosql数据到mysql数据
  • 存入nosql队列:去重复、排序数据
  • 检测商品最大数量:提示活动已结束

代码实现分析

第一层:商品展示层

知识点

页面/服务器优化、CDN网络加速、隐藏跳转页面、状态切换

  1. 秒杀页脚本
  • miao.sh
#!/usr/bin/env bash
date >> /root/456.txt
# 删除秒杀等待页面
rm -rf '/var/www/html/index.html'
# 复制秒杀页面到/var/www/html/index.html
cp '/var/www/html/index_sale.html' '/var/www/html/index.html'
  1. 计划任务
  • crontab linux计划任务
# 目前每分钟执行一次,具体各自配置
*/1 * * * * root /bin/miao.sh
  1. 秒杀结束
  • set_file.phpindex_over.html覆盖/var/www/html/index.html
<?php
//第一步:删除文件
$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);

第二层:用户登记层

知识点

格外增加:token加/解密、ajax跨域

<!DOCTYPE html>
<html lang="en">

<head> 
    <meta charset="UTF-8"> 
    <meta http-equiv="X-UA-Compatible" content="IE=edge"> 
    <meta name="viewport" content="width=device-width, initial-scale=1.0"> 
    <title>Document</title>
</head>

<body> 
    <script> 
        var url = "./miaosha.php";
        $("#qianggou").click(function () {
            var myphone = $("#myphone").val();
            var mynumber = $("#mynumber").val();
            var data = {
                'phone': myphone,
                'number': mynumber,
            };
        });
        $.ajax({
            url: url,
            data: data,
            dataType: 'jsonp',
            jsonp: "callback",//传递给请求处理程序或页面的,用以获取jsonp回调函数名的参数名(默认为:callback) 
            jsonpCallback: "success_jsonpCallback",//自定义的jsonp回调函数名称,默认为jquery自动生成的随机函数 
            success: function (cc) {
                if (cc.msg = "ok") {
                    $.cookie('miao', 'ok')
                }
            },
            error: function () {
                $.cookie('miao', null)
            },
            timeout: 300
        });
        //检测是否秒杀了 
        var miao =   $.cookie('miao')
        if (miao) {
            alert('你已秒杀');
        }
    </script>
</body>

</html>

第三层:数据接入层

知识点

数据校验、存入队列、商品数量检测

#miaosha.php
<?php

namespace miaosha;
//允许指定域名访问、防止跨域
header('Access-Control-Allow-Origin:http://xxxxx.cn');
$redis = new \Redis();
//获取$.ajax提交的数据
$value = ['phone' => 'xxxx', 'number' => '1'];
$value = serialize($value);

if (setValue($value) == "overflow") {
    //执行set_file.php秒杀结束
} else {
    $data = ['msg' => 'ok'];
}

//返回结果到前台
$callback = $_GET['callback'];
echo $callback . '(' . json_encode($data) . ')';

function setValue($value)
{
    $redis = new \Redis();
    //设置基数标志位 
    if (!$redis->get('flat')) {
        $redis->set('flat', 1);
    }
    //检测溢出,最大100 
    if ($redis->get('flat') > 100) {
        return 'overflow';
    }
    //插入非重复数据 
    if ($redis->zAdd('miaoKey', $redis->get('flat'), $value)) {
        $redis->incr('flat');
    }
}

function getValue()
{
    $redis = new \Redis();
    return $redis->zRange('miaoKey', 0, -1);
}

第四层:数据处理层

知识点

数据持久化

#set_mysql.php
<?php
//转存信息,进入到mysql进行数据持久化 
 $redis = new \Redis();
 $data = $redis->zRange('miaoKey', 0, -1);
//插入mysql....

抢购升级

加机器(简单粗暴),高峰过后会浪费

  1. 系统解耦(资源隔离,当前业务放在单独的集群上面)
  2. 限流和过载保护(根据后端承载能力,进行限流,防止全网挂掉,使用redis承载海量QPS)
  3. 高峰期做docker弹性扩缩容处理
  4. 做一套独立的秒杀系统(秒杀系统挂了,也不影响其他正常运行)
  5. 整个系统采用GO重新开发,极大提高了系统的性能(十台php可能才承载2万QPS,十台go能承载50万QPS)
  6. 降级预案
  7. 分析异常请求,设置黑白名单

秒杀接入层 1.长连接 2.ip黑名单 3.抢购开关(突发事件,需要关闭) 4.url校验 5.refer白名单 6.id黑名单

来源

大型PHP电商网站商品秒杀功能实现思路分析