当前位置: 首页 > news >正文

安徽智农网络信息技术服务有限公司 网站开发网站友情链接出售

安徽智农网络信息技术服务有限公司 网站开发,网站友情链接出售,wordpress 主题 html5 左右滑动切换文章,西安电子商务网站开发原标题:PHP用redis解决超卖的问题前言在商品秒杀活动中,比如商品库存只有100,但是在抢购活动中可能有200人同时抢购,这样就出现了并发,在100件商品下单完成库存为0了还有可能继续下单成功,就出现了超卖。为…

原标题:PHP用redis解决超卖的问题

前言

在商品秒杀活动中,比如商品库存只有100,但是在抢购活动中可能有200人同时抢购,这样就出现了并发,在100件商品下单完成库存为0了还有可能继续下单成功,就出现了超卖。

为了解决这个问题,今天我主要讲一下用redis队列的方式处理。redis有list类型,list类型其实就是一个双向链表。通过lpush,pop操作从链表的头部或者尾部添加删除元素。这使得list即可以用作栈,也可以用作队列。先进先出,一端进,一端出,这就是队列。在队列里前一个走完之后,后一个才会走,所以redis的队列能完美的解决超卖并发的问题。

解决秒杀超卖问题的方法还有比如:1.使用mysql的事务加排他锁来解决;2.使用文件锁实现。3.使用redis的setnx来实现锁机制等。

实现原理

将商品库存循环lpush到num里,然后在下单的时候通过rpop每次取出1件商品,当num的值为0时,停止下单。

第1步创建表

一共有三张表,分别是:订单表、商品表、日志表。

1.订单表 CREATE TABLE `ims_order` (

`id` int(11) NOT NULL AUTO_INCREMENT,

`order_sn` char(32) NOT NULL,

`user_id` int(11) NOT NULL,

`status` int(11) NOT NULL DEFAULT '0',

`goods_id` int(11) NOT NULL DEFAULT '0',

`sku_id` int(11) NOT NULL DEFAULT '0',

`number` int(11) NOT NULL,

`price` int(10) NOT NULL COMMENT '价格:单位为分',

`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,

PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=5820 DEFAULT CHARSET=utf8 COMMENT='订单表' 2.商品表 CREATE TABLE `ims_hotmallstore_goods` (

`id` int(11) unsigned NOT NULL AUTO_INCREMENT,

`name` varchar(50) NOT NULL COMMENT '商品名称',

`type_id` int(11) NOT NULL COMMENT '商品分类',

`img` text NOT NULL COMMENT '商品图片',

`money` decimal(10,2) NOT NULL COMMENT '售价',

`money2` decimal(10,2) NOT NULL COMMENT '原价',

`is_show` int(11) NOT NULL DEFAULT '1' COMMENT '1.上架2.下架',

`uniacid` int(11) NOT NULL COMMENT '小程序id',

`inventory` int(11) NOT NULL COMMENT '库存',

`details` text NOT NULL COMMENT '详情',

`store_id` int(11) NOT NULL COMMENT '商家id',

`sales` int(11) NOT NULL COMMENT '销量',

`logo` varchar(100) NOT NULL,

`num` int(11) NOT NULL,

`is_gg` int(11) NOT NULL DEFAULT '2' COMMENT '是否开启规格',

PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 3.日志表 CREATE TABLE `ims_order_log` (

`id` int(11) NOT NULL AUTO_INCREMENT,

`status` int(11) NOT NULL DEFAULT '0',

`msg` text CHARACTER SET utf8,

`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,

PRIMARY KEY (`id`),

KEY `status` (`status`)

) ENGINE=InnoDB AUTO_INCREMENT=4562 DEFAULT CHARSET=gb2312 COMMENT='订单日志表' 第2步写代码 class Test {

private static $instance = null;

// 用单列模式 实例化Redis

public static function Redis

{

if (self::$instance == null) {

$redis=new Redis;

$redis->connect('127.0.0.1',6379);

self::$instance = $redis;

}

return self::$instance;

}

// 将商品库存循环到lpush的num里

public function doPageSaveNum

{

$redis=self::Redis;

$goods_id=1;

$sql="select id, num, money from ims_hotmallstore_goods where id=".$goods_id;

$goods=pdo_fetch($sql);

if(!empty($goods)){

for($i=1; $i<=$goods['num']; $i++){

$redis->lpush('num',$i);

}

die('成功!');

}else{

$this->echoMsg(0,'商品不存在。');

}

}

// 抢购下单

public function doPageGoodsStore

{

$goods_id=1;

$sql="select id, num, money from ims_hotmallstore_goods where id=".$goods_id;

$goods=pdo_fetch($sql);

$redis=self::Redis;

$count=$redis->rpop('num');//每次从num取出1

if($count==0){

$this->echoMsg(0,'no num redis');

}

$this->doPageGoodsOrder($goods,1);

}

// 保存日志

public function echoMsg($status,$msg,$_data="")

{

$data=json_encode(array('status'=>$status,'msg'=>$msg,'data'=>$_data),JSON_UNESCAPED_UNICODE);

$order_log['status']=$status;

$order_log['msg']=$msg;

$order_log['create_time']=time;

pdo_insert('order_log',$order_log);

die($data);

}

public function orderNo

{

return date('ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid, 7, 13), 1))), 0, 8);

}

// 下单更新库存

public function doPageGoodsOrder($goods,$goods_number)

{

$orderNo=$this->orderNo;

$number=$goods['num']-$goods_number;

if($number<0){

$this->echoMsg(0,'已没有库存');

}

$user_id=rand(1,500);

$order['user_id']=$user_id;

$order['goods_id']=$goods['id'];

$order['number']=$goods_number;

$order['price']=$goods['money'];

$order['status']=1;

$order['sku_id']=2;

$order['order_sn']=$orderNo;

$order['create_time']=date('Y-m-d H:i:s');

pdo_insert('order',$order);

$sql="update ims_hotmallstore_goods set num=num-".$goods_number." where num>0 and id=".$goods['id'];

$res=pdo_query($sql);

if(!empty($res)){

$this->echoMsg(1,'库存扣减成功'.$number);

}

$redis=self::Redis;

$redis->lpush('num',$goods_number);

$this->echoMsg(0,'库存扣减失败'.$number);

}

}

// 调用--将商品库存循环到lpush的num里

if($_GET['i']==1){

$model = new Test;

$model->doPageSaveNum;

}

// 调用--高并发抢购下单

if($_GET['i']==2){

$model = new Test;

$model->doPageGoodsStore;

} 第3步并发测试

1.先手动执行: http://127.0.0.1/wqchunjingsvn/web/index.php?i=1 ,将商品库存循环保存到lpush的num里。

2.这里我用Apache的ab测试,安装方法本文最后做补充。打开终端,然后执行: ab -n 1000 -c 200 http://127.0.0.1/wqchunjingsvn/web/index.php?i=2

(-n发出1000个请求,-c模拟200并发,请求数要大于或等于并发数。相当1000人同时访问,后面是测试url )

3.观察是否执行成功,执行结果如下图,说明执行成功。

ff2c1bdedcb35da92fae4c15713706bd.png

第4步查看数据表

1.查看订单表,总订单数量为100,如下图,没问题。

2e3244ae1c149413b87ac5929be3b14e.png

2.查看商品库存,已经由原来的100变成0,也没问题。

8187ed1bc6551ce277535009adfc0322.png

3.查看日志表,总共137条记录,其中status为1的只有100条,也没问题。

ce797ff9f529aea94aedd72858f49073.png

ae75c8cd3cc99c3c0505f7a0144e8050.png

总结分析

1.方案可行,库存为0,没有出现超卖。

2.用Apache的ab测试高并发时需要注意Url地址不能拼接上带&号的参数,否则执行失败。返回搜狐,查看更多

责任编辑:

http://www.lbrq.cn/news/2392597.html

相关文章:

  • 郑州网站建设更好产品市场调研怎么做
  • 做网站属于无形资产还是费用环球贸易网
  • 贵州网站建设营销公司bt蚂蚁磁力
  • 网上有哪些购物网站网络营销战略的内容
  • wordpress申请网站企业宣传片
  • 想转行做网站营销策划思路及方案
  • wordpress资源站主题seo关键词优化推广外包
  • wordpress 代替cmsseo工程师是做什么的
  • 手机评测网站武汉网站推广公司排名
  • 如何用vps系统搭建企业网站以及邮箱系统企业在线培训系统
  • 做网站图片处理问题网络营销公司好不好
  • 信誉好的江苏网站建设最近一周热点新闻
  • 获取网站访客qq号码源码优化大师windows
  • 哈尔滨网站建设制作费用网站统计平台
  • 珠海做网站建设google网站登录入口
  • 做打鱼网站全网关键词云在哪里看
  • 余姚网站定制seo优化快排
  • 中山seo扣费郑州网站制作选择乐云seo
  • 上海网络推广公司网站外贸网站搭建推广
  • 今天哈尔滨最新通告seo的内容怎么优化
  • 域名怎么拿来做网站云客网平台
  • 不同网站建设特点网络营销品牌公司
  • 网站建设的上机报告培训机构是干什么的
  • 东莞网站建设北京seo推广外包
  • 中山精品网站建设方案安徽seo推广
  • 猪八戒上面还是淘宝上做网站技术好大庆网络推广
  • 做网站广告有哪些职位锦州seo推广
  • 微信公众号登录失败seo推广宣传
  • 湖北省疾病预防控制中心官方网站兰州网络推广关键词优化
  • 新浪图床 wordpress济南seo优化外包服务公司
  • 低代码平台ToolJet实战总结
  • 探索 Vue 3.6 的新玩法:Vapor 模式开启性能新篇章
  • CentOS7 内网服务器yum修改
  • LLM(Large Language Model)大规模语言模型浅析
  • 服务端高并发方案设计
  • 【Lua】闭包可能会导致的变量问题