• 关于一个秒杀或团抢活动的面试提问思考


    RT: 

    一个秒杀系统,当前物品有100个,活动上线有2000W用户参与,怎么设计这个架构。实现秒杀?

    思考:

    恶意刷单、页面静态化、CDN、缓存、域名、图片服务器、分布式、队列、高并发、流量削峰、RPC。

    订单库存有限、尽量快速反馈用户结果。

    前端:

    1.商品详情下单页静态化,静态文件资源JS、CSS、IMG资源文件独立域名,资源文件CDN化或者自建suqid缓存服务器。 

    2.下单按钮可做防重复提交设置。用户点击下单按钮后,操作变灰。或借助cookie或者前端框架如avalon保存用户操作时间,js限制单位时间只能提交一次。

    3.防止URL直接提交恶意刷单。设置下单url有效期、URL可变化或使用表单令牌限制等。

    后端:

    前端已经防止了一些重复或不必要的请求传递给后端服务器。这时还是难以避免高并发。并发过大,可能会导致流量暴增,应用挂掉。

    1.秒杀系统独立域名独立部署,在高并发情况下就算服务宕机也不影响正常的下单系统。

    2.使用消息队列、或内存栅栏抵挡大量高并发请求。可以使用MQ或基于内存的K-V缓存服务器如Redis。

    方案一:使用MQ

    用户的请求,服务器接收后,首先写入消息队列。假如消息队列长度超过最大数量,则直接抛弃用户请求或跳转到错误页面。

    <?php
    
    $product_total = 100;
    $product_id = Request::instance()->getPost('product_id')
    $uid = Session::instance()->getUser()->getUid();
    
    
    if(!filterRequest($product_id,$uid) || !order($product_id,$product_total,$uid)){
        $this->redirectUrl('/error/404.html');
    }
    
    $this->redirectUrl('/success.html');
    
    
    function filterRequest(){
        //判断用户是否有购买资格
        if(){
            return false;
        }
        
        //其他判断
    }
    
    function order($productId,$productTotal,$uid){
        //判断是否总数大于等于库存
        if($productTotal >= Redis::instance()->scard($productId)){
            return false;
        }
        
        //追加用户为可购买
        $ret = Redis::instance()->sadd($productId, $uid);
        //设置一天有效时间
        Redis::instance()->expire($productId,86400);
        
        return $ret;
    }
    View Code

    待续。。。。。。

    PS:

    关于消息队列的使用

  • 相关阅读:
    Git`s Operation
    从volatile说到,i++原子操作,线程安全问题
    sql中的几种删除方式
    Hibernate&MyBatis different
    集合问答
    Data Struct and Data Type
    Hash table and application in java
    idea`s shortcut key
    001--idea第一个报错JNI报错
    recyclebin
  • 原文地址:https://www.cnblogs.com/phpdragon/p/6741620.html
Copyright © 2020-2023  润新知