文档章节

用redis做一个简单的秒杀

 蛋定龙
发布于 2015/10/05 01:24
字数 611
阅读 4873
收藏 22
下面是一个简单的下单操作
<?php
include "MMysql.class.php";
$configArr=[
	'host'=>,
	'port'=>,
	'user'=>,
	'passwd'=>,
	'dbname'=>,
];
$db = new MMysql($configArr);
$sql="select * from sdb_b2c_products where product_id='38'";
$product=$db->doSql($sql);
if(!$product){
	echo "error:not find product";
	return;
}
$product=$product[0];
if($product['store']-$product['freez']<1){
	echo "error:no store";
	return;
}
$sql="select * from sdb_b2c_member_addrs where member_id='256187'";
$addr=$db->doSql($sql);
$addr=$addr[0];
$data=[
	'order_id'=>date('ymdHis').rand(100,999),
	'total_amount'=>$product['price'],
	'final_amount'=>$product['price'],
	'pay_status'=>'0',
	'createtime'=>time(),
	'shipping_id'=>'13',
	'shipping'=>'韵达',
	'member_id'=>'636389',
	'ship_area'=>$addr['area'],
	'shipname'=>$addr['name'],
	'ship_addr'=>$addr['addr'],
];
$order=$db->insert('sdb_b2c_orders',$data);
if($order){
	$sql="update sdb_b2c_products set freez=freez+1 where product_id='38'";
	$db->doSql($sql);
	echo "order create success";
	return;
}else{
	echo "error:order create fail";
	return;
}

?>

代码解释为:

在商品表中找到商品,获取实际库存和虚拟库存,如果时间库存减去虚拟库存小于1,则表示没有库存了

如果有实际库存,则去找memeber_id为'256187' 的会员收货地址信息,然后创建订单

如果订单创建成功,则更新虚拟库存。

 

 

用jmeter测试了在并发下的效果,设置500个线程去模拟并发

测试前设置实际库存store为50,虚拟库存freez为0,正常情况下freez只能达到50,否则就会有超卖的情况

实际测试,在高并发的情况下freez通常都大于50,在54左右。

由于获取库存是否还有,到更改库存中间有一定的时间差,所有高并发下会出现超卖的问题。

 

下面的代码经过修改,使用redis的list作为队列。

<?php
$store=50;
$redis=new Redis();
$result=$redis->connect('127.0.0.1',6379);
$res=$redis->llen('pro38');
echo $res;
$count=$store-$res;
for($i=0;$i<$count;$i++){
	$redis->lpush('pro38',1);
}
echo $redis->llen('pro38');
?>

上面是添加一个库存为50的redis的list

下面贴上下单代码

<?php
include "MMysql.class.php";
$configArr=[
	'host'=>'121.41.38.44',
	'port'=>'3306',
	'user'=>'yuancheng',
	'passwd'=>'yuancheng',
	'dbname'=>'laiyifendb',
];
$db = new MMysql($configArr);
$redis=new Redis();
$result=$redis->connect('127.0.0.1',6379);

$count=$redis->lpop('pro38');
if(!$count){
	echo "error:no store redis";
	return;
}
$sql="select * from sdb_b2c_products where product_id='38'";
$product=$db->doSql($sql);
if(!$product){
	echo "error:not find product";
	return;
}
$product=$product[0];
if($product['store']-$product['freez']<1){
	echo "error:no store";
	return;
}
$sql="select * from sdb_b2c_member_addrs where member_id='256187'";
$addr=$db->doSql($sql);
$addr=$addr[0];
$data=[
	'order_id'=>date('ymdHis').rand(100,999),
	'total_amount'=>$product['price'],
	'final_amount'=>$product['price'],
	'pay_status'=>'0',
	'createtime'=>time(),
	'shipping_id'=>'13',
	'shipping'=>'韵达',
	'member_id'=>'636389',
	'ship_area'=>$addr['area'],
	'shipname'=>$addr['name'],
	'ship_addr'=>$addr['addr'],
];
$order=$db->insert('sdb_b2c_orders',$data);
if($order){
	$sql="update sdb_b2c_products set freez=freez+1 where product_id='38'";
	$db->doSql($sql);
	echo "order create success";
	return;
}else{
	echo "error:order create fail";
	return;
}

?>

经过测试,此方法可以防止超卖的发生

 

© 著作权归作者所有

粉丝 3
博文 15
码字总数 8892
作品 0
青浦
私信 提问
加载中

评论(3)

m
mu0003
放到多台服务器的话在减扣redis库存的时候加上watch,就可以了。更细级别的话可以加上一个lock键值,通过操作lock进行减扣
蛋定龙 博主

引用来自“Elijah”的评论

考虑过把 这段代码部署到多太服务吗 ?
这里主要是redis,多台redis还没试过,php多台的话应该代码不用变什么,mysql多台那就有很多情况了,这里只是简单的秒杀,用了个redis的队列,复杂情况这个肯定不适合
Elijah
Elijah
考虑过把 这段代码部署到多太服务吗 ?
如何设计一个秒杀程序及避免超卖问题

很多的电商平台,在节假日如双十一,618等都会有商品描述的活动,今天和大家讨论一下,如何设计一个秒杀系统。 什么是秒杀 在一定的时间内几秒或者几分钟,对一定数量的库存进行出卖。 场景分...

时之令
2018/06/08
0
0
限时抢码(秒杀)设计

做之前看了不少关于秒杀商品的文章,其中有一篇觉得很好:【问底】徐汉彬:Web系统大规模并发——电商秒杀与抢购 抢码的逻辑比秒杀商品要简单太多,虽然简单但是高并发的问题却还是存在的,有...

尚小胖
2016/02/26
319
0
JavaWeb秒杀业务场景设计

秒杀业务场景设计问题经常被面试的时候被问到,在实际业务中,也常常需要实现,下面我们来看看如何实现秒杀业务. 秒杀业务,是典型的短时大量突发访问类问题 特点: 秒杀时网站的访问量大增; 秒杀...

小红牛
2018/06/11
0
0
用 Redis 轻松实现秒杀系统的构思

秒杀系统的架构设计 秒杀系统,是典型的短时大量突发访问类问题。对这类问题,有三种优化性能的思路: 1. 写入内存而不是写入硬盘、 2. 异步处理而不是同步处理、 3. 分布式处理 用上这三招,...

程序猿院长
04/12
79
0
java架构师之用Redis轻松实现秒杀系统

导论 曾经被问过好多次怎样实现秒杀系统的问题。昨天又在CSDN架构师微信群被问到了。因此这里把我设想的实现秒杀系统的价格设计分享出来。供大家参考。 秒杀系统的架构设计 秒杀系统,是典型...

Java高级架构师
2018/08/09
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Unable to connect to the server: x509: certificate signed by unknown authority

一、问题 当kubeadm安装完k8s后,使用kubectl命令,提示Unable to connect to the server: x509: certificate signed by unknown authority。 二、 解决 配置用户使用kubectl访问集群 $ mkdi...

人中泰迪
50分钟前
5
0
SpringBoot设置项目访问路径

今天配置Springboot项目访问路径遇到一个小坑,这里做一个记录。针对Springboot2.0以下版本和以上版本的配置方式是不同的。这里针对yml配置文件做记录,properties文件配置方式相同。 Spring...

王子城
56分钟前
7
0
Redis 序列化方式StringRedisSerializer、FastJsonRedisSerializer和KryoRedisSerializer

当我们的数据存储到Redis的时候,我们的键(key)和值(value)都是通过Spring提供的Serializer序列化到数据库的。RedisTemplate默认使用的是JdkSerializationRedisSerializer,StringRedis...

xiaolyuh
今天
5
0
jquery通过css的color属性实现选取特殊颜色的内容

今天一个朋友问到怎么使用jQuery选取特定颜色的内容,以前没有遇到过这样的需求。首先,很多人可能想到使用jQuery属性选择器来实现,这是不可以的,因为 color 是 css 的属性,而不是 html 的...

前端老手
今天
3
0
python3 网络爬虫开发实战 win10环境下 图形验证码识别需要安装的工具及地址

先下载安装tesseract exe文件 tesseract exe文件安装下载地址:https://digi.bib.uni-mannheim.de/tesseract/ win下直接下载双击安装即可,注意路径,下面用于配置环境变量。 参考网址: ht...

S三少S
今天
12
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部