Windows下redis配置
https://blog.csdn.net/success_a/article/details/105610299
以下是表结构
商品表
DROP TABLE IF EXISTS goods
;
CREATE TABLE goods
(
id
int(11) NOT NULL AUTO_INCREMENT,
count
int(11) DEFAULT NULL,
status
tinyint(1) DEFAULT NULL,
title
varchar(255) DEFAULT NULL,
amount
decimal(10,2) DEFAULT NULL,
PRIMARY KEY (id
)
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=latin1 COMMENT=‘商品表’;
抢购日志记录
DROP TABLE IF EXISTS log
;
CREATE TABLE log
(
id
int(11) NOT NULL AUTO_INCREMENT,
addtime
datetime DEFAULT NULL,
status
tinyint(1) DEFAULT NULL,
count
int(10) DEFAULT NULL,
PRIMARY KEY (id
)
) ENGINE=MyISAM AUTO_INCREMENT=1990 DEFAULT CHARSET=latin1 COMMENT=‘抢购日志记录’;
订单表
DROP TABLE IF EXISTS order
;
CREATE TABLE order
(
id
int(11) NOT NULL AUTO_INCREMENT,
order_sn
varchar(50) DEFAULT NULL,
user_id
int(10) DEFAULT NULL,
goods_id
int(10) DEFAULT NULL,
price
decimal(10,2) DEFAULT NULL,
status
tinyint(1) DEFAULT NULL,
addtime
datetime DEFAULT NULL,
PRIMARY KEY (id
)
) ENGINE=MyISAM AUTO_INCREMENT=1901 DEFAULT CHARSET=latin1 COMMENT=‘订单表’;
并在goods插入一件商品 库存为50(件)
直接上代码
<?php
/*
* redis商品秒杀
* 2020-4-19
* 樊某人
*/
namespace app\index\controller;
use think\Controller;
use think\Db;
class Seckill extends Controller
{
//秒杀入口
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');//删除并返回存储在中的列表的第一个元素key。
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');
}
//redis导入
public function redis()
{
$redis = new \Redis;
$redis->connect('127.0.0.1',6379);
$redis->auth('123456');
return $redis;
}
}
利用cmd进入apache/bin进行ab测压
E:\phpstudy\Apache\bin>ab -r -t 60 -n 3000 -c 600 http://127.0.0.1/tp5.1/public/index.php/index/seckill/index
最后日志表成功或失败
至此秒杀的功能基本实现 后续再去对其加工,欢迎大佬们提出宝贵的意见