https://blog.csdn.net/hao_mercury/article/details/79178735
基於以上鏈接大佬代碼的實驗 感謝~

首先在mysql創建數據庫 商品表,搶購日志記錄表,訂單表;
並在goods插入一件商品 庫存為50(件)

第二步下載Redis,網上教程挺多的不闡述,因為tp5自帶的Redis拓展功能不夠齊全所以使用外置的Redis
注意php的版本匹配適應的php_igbinary.dll和php_redis.dll;
https://windows.php.net/downloads/pecl/releases/igbinary/(php_igbinary.dll)
https://windows.php.net/downloads/pecl/releases/redis/(php_redis.dll)
記得去php.ini下配置!!
;php_redis extension=php_igbinary.dll extension=php_redis.dll
先導入外置Redis。
public function redis(){
$redis=new \Redis;
//配置Redis本地ip和端口,因為我沒設置Redis的密碼所以不配置
//切記勿開啟tp5自帶的Redis
$redis->connect('127.0.0.1',6379);
return $redis;
}
直接上代碼吧 參考上面那位大佬的測試
<?php
namespace app\index\controller;
use think\Controller;
use think\Db;
class Index extends Controller{
public function redis(){
$redis=new \Redis;
$redis->connect('127.0.0.1',6379);
return $redis;
}
//秒殺的入口
public function index(){
$id="1";//設置商品id
// 運行一次redisinit模擬入庫Redis50次,運行一次屏蔽再進行壓力測試
// $this->redisinit();
if(!$id) {
//如果沒有id為1的商品則記錄一次失敗日志狀態為:0
return $this->insertlog(0);
}
// 接入Redis
$redis=$this->redis();
// 移出Redis中goods_store隊列中的第一個元素,詳情參考Redis的lpop方法
$count=$redis->lpop('goods_store');
if(!$count){
// 如果goods_store隊列中沒有數據則搶購失敗,記錄一次失敗日志(相當於沒有庫存搶購失敗)
$this->insertlog(0);
return false;
}else{
// 創建訂單號
$orderrsn= $this->build_order_no();
// 隨機創建搶購用戶id
$uid=rand(0,9999);
//記錄狀態
$status= 1;
// 查找goods表中的庫存
$data=Db::table("goods")->field("count,amount")->where("id",$id)->find();
if(!$data){
// 沒有則記錄一次搶購失敗日志
return $this->insertlog(0);
}
// goods商品存在庫存時記錄搶購成功,即生成訂單一次
$result= Db::table("order")->insert(['order_sn'=>$orderrsn,'user_id'=>$uid,'goods_id'=>$id,'price'=>'50','status'=>$status,'addtime'=>'datetime']);
// 生成訂單一次后,goods商品的庫存-1,setDec()方法詳情參考tp5手冊
$res=Db::table("goods")->where("id",$id)->setDec("count");
if($res){
// 下單成功的話記錄一次搶購成功日志 狀態為:1
$this->insertlog(1);}
else{
// 失敗時為:0
$this->insertlog(0);
}
}
}
//記錄日志到log表的方法
public function insertlog($status){
$result= Db::execute('insert into log (addtime,status, count) values (:addtime,:status, :count)',['addtime'=>'datetime','status'=>$status,'count'=>'1']);
return $result;
}
// 隨機創建訂單號方法
public function build_order_no(){
return date('ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
}
// 初始化Redis 模擬庫存50個
public function redisinit(){
$store=50;
$redis=$this->redis();
// 刪除goods_store中一條緩存
$redis->del('goods_store');
// 返回goods_store的長度,此時為 0
$res=$redis->lLen('goods_store');
$count=$store-$res;
for($i=0;$i<$count;$i++){
// 列表推進50個 模擬庫存50
$redis->lPush('goods_store',1);
}
echo $redis->lLen('goods_store');
}
}
進行壓力測試,奇怪的是不能直接測試www.tp5.com這樣的url 可是在后面加個 \ 確執行了......和上文的有出入 似乎是因為我tp5配置的原因 無法使用www.tp5.com\id\1這樣的測試 所以在獲取商品id的方面進行了改動

最后查詢goods表發現商品並沒有超賣現象,日志表成功記錄所以搶購成功或者搶購失敗的日志。
還是有不懂的地方總之能 自己動手寫一遍 收益良多~~
小白一枚 不喜勿噴~~如果我說錯了請指教,如果覺得蠢的話就蠢唄 哈哈哈
