<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.pstee.com:青铜峡市| www.krowstore.com:义马市| www.auburnoysterbar.com:桃江县| www.xybww.cn:景宁| www.medicalspaofrye.com:麦盖提县| www.zjyrjy.com:平昌县| www.cheap-uggboots4u.com:江安县| www.ywijx.com:朝阳县| www.g5669.com:大城县| www.amzabawki.com:福海县| www.huwei688.com:城口县| www.weieixuan.com:赤壁市| www.tm046.com:横山县| www.blogbebas.com:临颍县| www.sun-automation.com:金秀| www.jiaxinleather.com:锡林郭勒盟| www.acllo.com:太白县| www.news2come.com:格尔木市| www.elegooo.com:彩票| www.tmhatter.com:贡觉县| www.freemovieswatch.org:印江| www.jugouyao.com:九龙城区| www.w-b-z.com:岢岚县| www.morethanmusichk.org:通榆县| www.zbtaocidao.com:江阴市| www.zzysww.com:富川| www.pmdsales.com:阳山县| www.wingsofsong.org:永嘉县| www.geile-sexdate.com:曲麻莱县| www.cp3325.com:杭锦后旗| www.uckkimya.com:山丹县| www.shfyhg.com:定襄县| www.dessertsstraightup.com:嵩明县| www.romanyrestaurant.com:瑞昌市| www.new-sg.com:竹山县| www.lw338.com:固原市| www.xfkqf.com:克东县| www.szbaled.com:邵阳市| www.alphaaidtraining.com:华池县| www.mayaramegiolaro.com:定陶县| www.chansamabut.com:原阳县| www.yuanfangauction.com:宜川县| www.paintsprayerelite.com:澎湖县| www.nbuyi.com:澄城县| www.bloghomedepot.com:台东县| www.ysygs.com:深水埗区| www.aetosz.com:通海县| www.fzv0.com:醴陵市| www.cp3585.com:锡林浩特市| www.qslqsl.com:阿图什市| www.brianpuspos.com:云浮市| www.shguwanpm.com:全南县| www.547291.com:类乌齐县| www.0514dc.com:漾濞| www.lacettiid.com:宁安市| www.sixsecondad.com:惠来县| www.moretoken.org:石林| www.xisepian.com:高雄市| www.ikemax.com:夏邑县| www.changdaoresort.com:尖扎县| www.yongqinlaw.com:介休市| www.itosee.com:菏泽市| www.petespencilart.com:宝兴县| www.cachuongcollagen.com:堆龙德庆县| www.taynelemon.com:白水县| www.zydlgzdw.com:庆城县| www.wwwhg3633.com:榆林市| www.gabrielmoginot.com:日土县| www.busybeesflorist.com:江门市| www.top10logo.com:白城市| www.hg41678.com:邢台市| www.donorsnet.net:陆川县| www.colangelosbakery.com:青田县| www.aiweizhi.com:萨嘎县| www.pressplaycoach.com:霍山县| www.ntlxx.com:云龙县| www.sortpix.com:临泉县| www.southfumigation.com:仁寿县| www.yiju188.com:中江县| www.wainini.com:瑞丽市| www.gq992.com:金沙县| www.nghethuatbongbay.com:伊宁县| www.jwbzf.com:开远市| www.dobene.com:茌平县|