<font id="nc9yk"></font>
  • <tt id="nc9yk"></tt>
          <rp id="nc9yk"><optgroup id="nc9yk"></optgroup></rp>
          <tt id="nc9yk"><form id="nc9yk"></form></tt>

            <cite id="nc9yk"></cite>

            Thinkphp5+Redis實現商品秒殺代碼實例講解

             更新時間:2020年12月29日 16:54:56   作者:下頁、再停留  
            這篇文章主要介紹了Thinkphp5+Redis實現商品秒殺代碼實例講解,代碼和步驟講解的很清楚,有需要的同學可以借鑒參考下

            環境:wamp,redis

            要求:安裝WAMP,Redis,以及為PHP安裝Redis擴展

            秒殺功能大致思路:獲取緩存列表的長度,如果長度(llen)等于0,就停止秒殺,即秒殺失敗,如果長度大于0,則繼續運行,先從緩存中移除一個元素(lpop),再進行數據庫操作(添加訂單表,商品庫存數量減一),如果再進一個人秒殺,就再走一遍流程,循環往復。

            一、安裝Redis擴展

            1.查看PHP版本信息

            打開phpinfo.php,查看PHP版本,我的是PHP7.3.4,還有一個需要注意Architecture x64

            2.下載擴展文件

            https://pecl.php.net/package/redis

            https://pecl.php.net/package/igbinary

            根據自己環境,選擇合適的版本

            3.解壓

            解壓下載的壓縮包,并把php_redis.dll、php_redis.pdb和php_igbinary.dll、php_igbinary.pdb四個文件,移至自己PHP版本對應目錄下的ext文件夾下E:\phpstudy_pro\Extensions\php\php7.3.4nts\ext

            4.修改php.ini

            添加如下代碼:

            extension=php_igbinary.dll
            extension=php_redis.dll

            如果有這兩句可以把前面的分號刪掉,沒有就自己添加上,要注意順序,php_igbinary.dll 要在php_redis.dll 前面

            5.重啟Apache

            重啟后,再運行phpinfo.php,查看是否安裝成功

            二、數據結構

            一共三張表,ab_goods商品表,ab_order訂單表,ab_log日志表

            商品表

            訂單表

            日志表 記錄秒殺信息

            三、代碼

            <?php
            namespace app\index\controller;
            use think\Controller;
            use think\Db;
            use think\cache\driver\Redis;
            
            class Miaosha extends Controller
            {
            
             private $redis = null;
             private $cachekey = null; //緩存變量名
             private $basket = []; //私有數組,存放商品信息
            
             private $store = 50;
            
             /**
             * 購物車初始化,傳入用戶id
             */
             public function __construct()
             {
             parent::__construct();
            
             $this->redis = new \Redis(); // 實例化
             $this->redis->connect('127.0.0.1','6379');
             $this->redis->auth('zxf123456');
            
             }
            
             /**
             * 秒殺初始化
             */
             public function Ms_init()
             {
             // 刪除緩存列表
             $this->redis->del($this->cachekey);
            
             $len = $this->redis->llen($this->cachekey);
             $count = $this->store - $len;
            
             for ($i=0; $i < $count; $i++) { 
            
             // 向庫存列表推進50個,模擬50個商品庫存
             $this->redis->lpush($this->cachekey,1);
             }
            
             echo "庫存初始化完成:".$this->redis->llen($this->cachekey);
             }
             
            
             /**
             * 秒殺入口
             */
             public function index()
             {
             $id = 1; //商品編號
             
             if (empty($id)) {
             // 記錄失敗日志
             return $this->writeLog(0,'商品編號不存在'); 
             }
            
             // 計算庫存列表長度
             $count = $this->redis->llen($this->cachekey);
            
             // 先判斷庫存是否為0,為0秒殺失敗,不為0,則進行先移除一個元素,再進行數據庫操作
             if ($count == 0) { //庫存為0
            
             $this->writeLog(0,'庫存為0');
             echo "庫存為0";
             exit;
            
             }else{
             // 有庫存
             //先移除一個列表元素
             $this->redis->lpop($this->cachekey);
            
             $ordersn = $this->build_order_no(); //生成訂單
             $uid = rand(0,9999); //隨機生成用戶id
             $status = 1;
             // 再進行數據庫操作
             $data = Db::table('ab_goods')->field('count,amount')->where('id',$id)->find(); //查找商品
            
             if (!$data) {
             return $this->writeLog(0,'該商品不存在');
             }
            
             $insert_data = [
             'order_sn' => $ordersn,
             'user_id' => $uid,
             'goods_id' => $id,
             'price' => $data['amount'],
             'status' => $status,
             'addtime' => date('Y-m-d H:i:s')
             ];
            
             // 訂單入庫
             $result = Db::table('ab_order')->insert($insert_data);
             // 自動減少一個庫存
             $res = Db::table('ab_goods')->where('id',$id)->setDec('count');
            
             if ($res) {
             echo "第".$count."件秒殺成功";
             $this->writeLog(1,'秒殺成功');
             }else{
             echo "第".$count."件秒殺失敗";
             $this->writeLog(0,'秒殺失敗');
             }
             }
             }
            
             /**
             * 生成訂單號
             */
             public function build_order_no()
             {
             return date('ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
             }
            
             /**
             * 生成日志 1成功 0失敗
             */
             public function writeLog($status = 1,$msg)
             {
             $data['count'] = 1;
             $data['status'] = $status;
             $data['addtime'] = date('Y-m-d H:i:s');
             $data['msg'] = $msg;
             return Db::table('ab_log')->insertGetId($data);
             }
            
            }

            四、壓力測試

            使用apache壓力測試工具 AB 測試,模擬多用戶秒殺商品,模擬60秒內發起3000個請求,并發600次,秒殺50個庫存商品

            AB測試相關參數說明

            • -r 指定接收到錯誤信息時不退出程序
            • -t 等待響應的最大時間
            • -n 指定壓力測試總共的執行次數
            • -c 用于指定壓力測試的并發數

            1.初始化50個庫存,運行ms_init方法

            2.測試   命令行:

            E:\phpstudy_pro\Extensions\Apache2.4.39\bin>ab -r -t 60 -n 3000 -c 1000 http://gouwuche.zxf/index/miaosha/index  

              3.檢測數據庫數據

            日志表狀態為1(秒殺成功)的數據有50人,訂單表里的訂單數也是50條,商品表里的商品數量變成了0(測試之前是50),商品秒殺成功完成!

            如果不用redis而是直接用mysql的話,商品表訂單的數量count會變成負數,而秒殺成功的人數也多余50人,訂單表里的訂單數量也多余50條(新測),下面是直接用Mysql的例子;

            public function sqlMs()
             {
             $id = 1; //商品編號
            
             $count = 50;
             $ordersn = $this->build_order_no(); //生成訂單
             $uid = rand(0,9999); //隨機生成用戶id
             $status = 1;
             // 再進行數據庫操作
             $data = Db::table('ab_goods')->field('count,amount')->where('id',$id)->find(); //查找商品
            
             // 查詢還剩多少庫存
             $rs = Db::table('ab_goods')->where('id',$id)->value('count');
             if ($rs <= 0) {
             
             $this->writeLog(0,'庫存為0');
             }else{
            
             $insert_data = [
             'order_sn' => $ordersn,
             'user_id' => $uid,
             'goods_id' => $id,
             'price' => $data['amount'],
             'status' => $status,
             'addtime' => date('Y-m-d H:i:s')
             ];
            
             // 訂單入庫
             $result = Db::table('ab_order')->insert($insert_data);
             // 自動減少一個庫存
             $res = Db::table('ab_goods')->where('id',$id)->setDec('count');
            
             if ($res) {
             echo "第".$data['count']."件秒殺成功";
             $this->writeLog(1,'秒殺成功');
             }else{
             echo "第".$data['count']."件秒殺失敗";
             $this->writeLog(0,'秒殺失敗');
             }
             }
             }

            到此這篇關于Thinkphp5+Redis實現商品秒殺的文章就介紹到這了,更多相關Thinkphp5+Redis實現商品秒殺內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持腳本之家!

            相關文章

            • ThinkPHP3.1新特性之命名范圍的使用

              ThinkPHP3.1新特性之命名范圍的使用

              ThinkPHP3.1的命名范圍功能,給模型操作提供了一系列的(連貫操作)封裝,讓你更方便的查詢和操作數據。這篇文章主要介紹了ThinkPHP3.1命名范圍的使用,需要的朋友可以參考下
              2014-06-06
            • php redis setnx分布式鎖簡單原理解析

              php redis setnx分布式鎖簡單原理解析

              這篇文章主要介紹了php redis setnx分布式鎖簡單原理解析,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
              2020-10-10
            • PHP錯誤處理函數register_shutdown_function使用示例

              PHP錯誤處理函數register_shutdown_function使用示例

              這篇文章主要介紹了PHP錯誤處理函數register_shutdown_function使用示例,需要的朋友可以參考下
              2017-07-07
            • 基于JQuery+PHP編寫砸金蛋中獎程序

              基于JQuery+PHP編寫砸金蛋中獎程序

              砸金蛋被廣泛應用于慶典活動、商家促銷、電視娛樂等場合,它的趣味、懸念能迅速活躍現場氣氛,同樣,我們也可以將砸金蛋應用到WEB網站上,用于開展線上活動,本文將使用jQuery+PHP講解如何實現一個WEB砸金蛋程序,需要的朋友一起來學習吧
              2015-09-09
            • Yii2使用小技巧之通過 Composer 添加 FontAwesome 字體資源

              Yii2使用小技巧之通過 Composer 添加 FontAwesome 字體資源

              前天幫同事改個十年前的網站 bug,頁面上一堆 include require 不禁讓人抱頭痛哭。看到 V2EX 上的討論說,寫 PHP 不用框架等同于耍流氓。Yii Framework 是我使用了 2 年多的 PHP 框架,器大活好,皮實耐操。 Yii2 還在 Beta 中,不過不影響拿來預研。
              2014-06-06
            • 詳解PHP中strlen和mb_strlen函數的區別

              詳解PHP中strlen和mb_strlen函數的區別

              在PHP中,strlen與mb_strlen是求字符串長度的函數,但是對于一些初學者來說,如果不看手冊,也許不太清楚其中的區別
              2014-03-03
            • Thinkphp5框架實現獲取數據庫數據到視圖的方法

              Thinkphp5框架實現獲取數據庫數據到視圖的方法

              這篇文章主要介紹了Thinkphp5框架實現獲取數據庫數據到視圖的方法,涉及thinkPHP5數據庫配置、讀取、模型操作及視圖調用相關操作技巧,需要的朋友可以參考下
              2019-08-08
            • Laravel框架實現model層的增刪改查(CURD)操作示例

              Laravel框架實現model層的增刪改查(CURD)操作示例

              這篇文章主要介紹了Laravel框架實現model層的增刪改查(CURD)操作,結合實例形式分析了Laravel框架模型model層進行數據庫的增刪改查操作具體實現技巧,需要的朋友可以參考下
              2018-05-05
            • 基于PHP實現短信驗證碼接口(容聯運通訊)

              基于PHP實現短信驗證碼接口(容聯運通訊)

              本文分步驟給大家講解了短信驗證碼接口(容聯運通訊)實現代碼,非常不錯,具有參考借鑒價值,感興趣的朋友一起看看吧
              2016-09-09
            • 基于laravel where的高級使用方法

              基于laravel where的高級使用方法

              今天小編就為大家分享一篇基于laravel where的高級使用方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
              2019-10-10

            最新評論

            hao500彩票 www.baby-photos.net:伊吾县| www.lnwnk.com:巴彦淖尔市| www.hearthemlive.com:舟山市| www.sanxinghr.com:封开县| www.henerhq.com:洛川县| www.crystaltunisia.com:南开区| www.beijingshengbo.com:蚌埠市| www.k2920.com:曲阳县| www.paknts.com:泸水县| www.trottracker.com:阳山县| www.casagourmande.com:邳州市| www.xybww.cn:蒙山县| www.asenim.org:财经| www.shopjasonmarkk.com:宁都县| www.wingsofsong.org:田阳县| www.wingflytravel.com:贡觉县| www.papigotravel.com:和龙市| www.ds779.com:吉林省| www.well39.com:广宗县| www.conet-working.com:金山区| www.zjhgx.com:永吉县| www.summonerscentral.com:七台河市| www.lw338.com:永顺县| www.aujardindesgraines.com:徐汇区| www.bloghomedepot.com:新巴尔虎左旗| www.ahlikartu.com:通榆县| www.bdkindustries.com:静海县| www.bhwwz.com:重庆市| www.fnsbx.cn:若尔盖县| www.modasaatler.com:安远县| www.mathtuition.org:平罗县| www.pobohn.com:桦南县| www.tasdy7700.com:榆中县| www.lwshengfeng.com:昆山市| www.hobigoods.com:许昌市| www.illuminingtalks.org:安西县| www.wmeiyi888.com:宝山区| www.schpw.cn:鄂州市| www.sandillc.com:武宣县| www.satext.com:巩义市| www.lishanan.com:莆田市| www.busybeesflorist.com:台前县| www.mrtentllc.com:乃东县| www.tztrelleborg.com:马关县| www.aiqinhaiszx.com:子洲县| www.kyxjw.cn:会泽县| www.yadayang.com:琼结县| www.yfsco.com:嘉祥县| www.henglian-sh.com:蓬莱市| www.49website.com:青海省| www.razorcrusaders.com:宜州市| www.ossean.com:麻阳| www.ozcanis.com:杨浦区| www.amerous.com:珠海市| www.inhouse-outhouse.com:安泽县| www.kidizzle.com:宁德市| www.faplo.com:吉安市| www.zblrw.cn:洪湖市| www.forum-hosting.com:特克斯县| www.hg68345.com:苗栗县| www.yuezhan88.com:铁力市| www.626190.com:延吉市| www.submitbookmarkingsites.com:衡阳县| www.thedoveexperience.com:高台县| www.bionicandbiomech.com:肃北| www.dag9.com:太白县| www.changdaoresort.com:武川县| www.xawydz.com:金昌市| www.noxcuse.org:十堰市| www.uribaba.com:石城县| www.love0534.com:谢通门县| www.jjmatransportation.com:南丹县| www.whatsnewbondi.com:和顺县| www.j5dd.com:阆中市| www.cp7713.com:盖州市| www.the-youngers.org:石渠县| www.bmwbursa.com:玛多县| www.manlighting.com:荥阳市| www.therasmusfc.com:盐山县| www.hw8168.com:大庆市| www.sci-papers.org:大兴区| www.wobocai.com:阿勒泰市| www.bloggerjomblo.com:渭源县| www.4eda.com:常宁市|