pbootcms网站模板|日韩1区2区|织梦模板||网站源码|日韩1区2区|jquery建站特效-html5模板网

php處理搶購類功能的高并發(fā)請求

這篇文章主要為大家詳細介紹了php處理搶購類功能的高并發(fā)請求,具有一定的參考價值,感興趣的小伙伴們可以參考一下

本文以搶購、秒殺為例。介紹如何在高并發(fā)狀況下確保數(shù)據(jù)正確。
在高并發(fā)請求下容易參數(shù)兩個問題
1.數(shù)據(jù)出錯,導(dǎo)致產(chǎn)品超賣。
2.頻繁操作數(shù)據(jù)庫,導(dǎo)致性能下降。

測試環(huán)境

Windows7
apache2.4.9
php5.5.12
php框架 yii2.0
工具 apache bench (apache自帶高并發(fā)請求工具)。

通常處理方法

從控制器可以看出代碼思路。先查詢商品庫存。如果庫存大于0 ,則庫存減少1,同時生產(chǎn)訂單,錄入搶購者數(shù)據(jù)。

// 常規(guī)代碼處理高并發(fā)
  public function actionNormal(){
    // 查詢庫存
    $stock = Goods::find()->select('stock')->where(['goods_id'=>100001])->asArray()->one();
    // 判斷該商品是否還有庫存
    if ($stock['stock']>0) {
      // 庫存減一
      Goods::updateAllCounters(['stock' => -1],['goods_id'=>100001]);

      // 生產(chǎn)訂單(另外功能,暫且隨機賦值)
      $order = $this->build_order();

      // 秒殺信息入庫
      $model = new Highly();
      $model->order_id = $order;
      $model->goods_name = '秒殺商品';
      $model->buy_time = date('Y-m-d H:i:s',time());
      $model->mircrotime = microtime(true);
      if($model->save()===false){
        echo '未能成功搶購!';
      }else{
        echo '恭喜你,訂單<b>'.$order.'</b>搶購成功';
      }

    }else{
      echo '已被搶購一空!';
    }
  }

將商品庫存設(shè)置為20后,通過ab 配置200的并發(fā)請求。

ab -n 200 -c 200 http//localhost/highly/normal

執(zhí)行結(jié)果發(fā)現(xiàn)庫存變成了負值,商品超賣了。

php處理搶購類功能的高并發(fā)請求

原因比較簡單,在高并發(fā)請求下。在生產(chǎn)訂單,減少庫存之前,會優(yōu)先查詢到庫存結(jié)果。

優(yōu)化一:修改庫存數(shù)據(jù)類型

第一種優(yōu)化方法,從數(shù)據(jù)庫入手。既然查詢到的結(jié)果不準(zhǔn)確,那我就在庫存減少上做手腳。將庫存的數(shù)據(jù)類型改成無符號(不能有負值)。

代碼還是跟上面差不多,只是在庫存減1的地方做了個判斷。避免報錯。

public function actionNormal(){
    // 查詢庫存
    $stock = Goods::find()->select('stock')->where(['goods_id'=>100001])->asArray()->one();
    // 判斷該商品是否還有庫存
    if ($stock['stock']>0) {
      // 庫存減一
      if(Goods::updateAllCounters(['stock' => -1],['goods_id'=>100001])===false){
        echo "已被搶購一空!";
        return false;
      }

      // 生產(chǎn)訂單(另外功能,暫且隨機賦值)
      $order = $this->build_order();

      // 秒殺信息入庫
      $model = new Highly();
      $model->order_id = $order;
      $model->goods_name = '秒殺商品';
      $model->buy_time = date('Y-m-d H:i:s',time());
      $model->mircrotime = microtime(true);
      if($model->save()===false){
        echo '未能成功搶購!';
      }else{
        echo '恭喜你,訂單<b>'.$order.'</b>搶購成功';
      }

    }else{
      echo '已被搶購一空!';
    }
  }

這一次同樣200的并發(fā),執(zhí)行結(jié)果發(fā)現(xiàn)。數(shù)據(jù)正確,并不會出現(xiàn)超賣的情況。
思路其實也比較簡單。因為庫存不能為負值,當(dāng)庫存等于0時,如果還有值傳進來,則會報錯。請求被終止。

這種優(yōu)化方式,雖然避免了商品超賣的情況。但是在另一方面,請求仍然會對數(shù)據(jù)庫造成壓力。如果多個功能使用此數(shù)據(jù)庫,會造成性能下降厲害。

優(yōu)化二:redis

利用 redis list類型的pop的原子性。在操作數(shù)據(jù)庫前,做一個驗證。當(dāng)商品賣完后,就不允許再繼續(xù)進行數(shù)據(jù)庫操作。

// redis list 高并發(fā)測試
  public function actionRedis(){
    $redis = \Yii::$app->redis;
    // $redis->lpush('mytest',1);
    $order = $this->build_order();
    // echo $order;die;
    // echo $redis->llen('mytest');
    $reg = $redis->lpop('mytest');
    if (!$reg) {
      echo "笨蛋!已經(jīng)被搶光啦!";
      return false;
    }
    $redis->close();
    $model = new Highly();
    $model->order_id = $order;
    $model->goods_name = '秒殺商品';
    $model->buy_time = date('Y-m-d H:i:s',time());
    $model->mircrotime = microtime(true);

    if($model->save()===false){
      echo '未能成功搶購!';
    }else{
      echo '恭喜你,訂單<b>'.$order.'</b>搶購成功';
    }
  }
  // 給redis添加商品
  public function actionInsertgoods(){
    $count = yii::$app->request->get('count',0);
    if (empty($count)) {
      echo '大兄弟,你還沒告訴我需要上架多少商品呢!';
      return false;
    }
    $redis = \Yii::$app->redis;
    for ($i=0; $i < $count; $i++) { 
      $redis->lpush('mytest',1);
    }
    echo '成功添加了'.$redis->llen('mytest').'件商品。';
    $redis->close();

  }

這點的代碼,我寫了兩個方法。第一個方法是秒殺的代碼,第二個方法是給秒殺的商品設(shè)置數(shù)量。為了方便測試,我這里處理的比較簡單。

【網(wǎng)站聲明】本站除付費源碼經(jīng)過測試外,其他素材未做測試,不保證完整性,網(wǎng)站上部分源碼僅限學(xué)習(xí)交流,請勿用于商業(yè)用途。如損害你的權(quán)益請聯(lián)系客服QQ:2655101040 給予處理,謝謝支持。

相關(guān)文檔推薦

這篇文章主要介紹了PHP定義字符串的四種方式,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
下面小編就為大家分享一篇php 替換文章中的圖片路徑,下載圖片到本地服務(wù)器的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
下面小編就為大家分享一篇PHP給源代碼加密的幾種方法匯總(推薦),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
下面小編就為大家分享一篇php打開本地exe程序,js打開本地exe應(yīng)用程序,并傳遞相關(guān)參數(shù)方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
這篇文章主要介紹了PHP類的反射來實現(xiàn)依賴注入過程以及相關(guān)知識點分享,對此有興趣的朋友跟著小編學(xué)習(xí)下吧。
php遍歷一個文件夾內(nèi)的所有文件和文件夾,并刪除所有文件夾和子文件夾下的所有文件的代碼,通過遞歸方式實現(xiàn)達到清空一個目錄的效果。本文給大家分享實例代碼,需要的朋友參考
主站蜘蛛池模板: 磁力反应釜,高压釜,实验室反应釜,高温高压反应釜-威海自控反应釜有限公司 | 高温高压釜(氢化反应釜)百科| 河南砖机首页-全自动液压免烧砖机,小型砌块水泥砖机厂家[十年老厂] | 耐高温风管_耐高温软管_食品级软管_吸尘管_钢丝软管_卫生级软管_塑料波纹管-东莞市鑫翔宇软管有限公司 | 天津热油泵_管道泵_天津高温热油泵-天津市金丰泰机械泵业有限公司【官方网站】 | 即用型透析袋,透析袋夹子,药敏纸片,L型涂布棒-上海桥星贸易有限公司 | 杭州|上海贴标机-百科| 硬质合金模具_硬质合金非标定制_硬面加工「生产厂家」-西迪技术股份有限公司 | 南京泽朗生物科技有限公司-液体饮料代加工_果汁饮料代加工_固体饮料代加工 | 换网器_自动换网器_液压换网器--郑州海科熔体泵有限公司 | 二手光谱仪维修-德国OBLF光谱仪|进口斯派克光谱仪-热电ARL光谱仪-意大利GNR光谱仪-永晖检测 | 印刷人才网 印刷、包装、造纸,中国80%的印刷企业人才招聘选印刷人才网! | 上海平衡机-单面卧式动平衡机-万向节动平衡机-圈带动平衡机厂家-上海申岢动平衡机制造有限公司 | 塑钢件_塑钢门窗配件_塑钢配件厂家-文安县启泰金属制品有限公司 深圳南财多媒体有限公司介绍 | 土壤有机碳消解器-石油|表层油类分析采水器-青岛溯源环保设备有限公司 | 精密五金冲压件_深圳五金冲压厂_钣金加工厂_五金模具加工-诚瑞丰科技股份有限公司 | 泰国试管婴儿_泰国第三代试管婴儿_泰国试管婴儿费用/多少钱_孕泰来 | 氟塑料磁力泵-不锈钢离心泵-耐腐蚀化工泵厂家「皖金泵阀」 | 深圳货架厂_仓库货架公司_重型仓储货架_线棒货架批发-深圳市诺普泰仓储设备有限公司 | 风信子发稿-专注为企业提供全球新闻稿发布服务 | 灌装封尾机_胶水灌装机_软管灌装封尾机_无锡和博自动化机械制造有限公司 | 汽车水泵_汽车水泵厂家-瑞安市骏迪汽车配件有限公司 | 法兰连接型电磁流量计-蒸汽孔板节流装置流量计-北京凯安达仪器仪表有限公司 | 仓储笼_金属箱租赁_循环包装_铁网箱_蝴蝶笼租赁_酷龙仓储笼租赁 测试治具|过炉治具|过锡炉治具|工装夹具|测试夹具|允睿自动化设备 | 蒸压釜-陶粒板隔墙板蒸压釜-山东鑫泰鑫智能装备有限公司 | 深圳快餐店设计-餐饮设计公司-餐饮空间品牌全案设计-深圳市勤蜂装饰工程 | 全自动烧卖机厂家_饺子机_烧麦机价格_小笼汤包机_宁波江北阜欣食品机械有限公司 | 会议会展活动拍摄_年会庆典演出跟拍_摄影摄像直播-艾木传媒 | 北京律师事务所_房屋拆迁律师_24小时免费法律咨询_云合专业律师网 | 艺术涂料_进口艺术涂料_艺术涂料加盟_艺术涂料十大品牌 -英国蒙太奇艺术涂料 | 脉冲除尘器,除尘器厂家-淄博机械 | 企典软件一站式企业管理平台,可私有、本地化部署!在线CRM客户关系管理系统|移动办公OA管理系统|HR人事管理系统|人力 | 工控机-工业平板电脑-研华工控机-研越无风扇嵌入式box工控机 | 氧化铝球_高铝球_氧化铝研磨球-淄博誉洁陶瓷新材料有限公司 | 专业深孔加工_东莞深孔钻加工_东莞深孔钻_东莞深孔加工_模具深孔钻加工厂-东莞市超耀实业有限公司 | ALC墙板_ALC轻质隔墙板_隔音防火墙板_轻质隔墙材料-湖北博悦佳 | 学生作文网_中小学生作文大全与写作指导 | 一体化净水器_一体化净水设备_一体化水处理设备-江苏旭浩鑫环保科技有限公司 | 环球电气之家-中国专业电气电子产品行业服务网站! | 地磅-地秤-江阴/无锡地磅-江阴天亿计量设备有限公司_ | 盘煤仪,盘料仪,盘点仪,堆料测量仪,便携式激光盘煤仪-中科航宇(北京)自动化工程技术有限公司 |