亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 數(shù)據(jù)庫 > Redis > 正文

php結(jié)合redis實現(xiàn)高并發(fā)下的搶購、秒殺功能的實例

2020-10-28 21:38:18
字體:
供稿:網(wǎng)友

搶購、秒殺是如今很常見的一個應(yīng)用場景,主要需要解決的問題有兩個:

1 高并發(fā)對數(shù)據(jù)庫產(chǎn)生的壓力

2 競爭狀態(tài)下如何解決庫存的正確減少("超賣"問題)

對于第一個問題,已經(jīng)很容易想到用緩存來處理搶購,避免直接操作數(shù)據(jù)庫,例如使用Redis。

重點在于第二個問題

常規(guī)寫法:

查詢出對應(yīng)商品的庫存,看是否大于0,然后執(zhí)行生成訂單等操作,但是在判斷庫存是否大于0處,如果在高并發(fā)下就會有問題,導(dǎo)致庫存量出現(xiàn)負(fù)數(shù)

<?php$conn=mysql_connect("localhost","big","123456"); if(!$conn){ 	echo "connect failed"; 	exit; } mysql_select_db("big",$conn); mysql_query("set names utf8");$price=10;$user_id=1;$goods_id=1;$sku_id=11;$number=1;//生成唯一訂單function build_order_no(){  return date('ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);}//記錄日志function insertLog($event,$type=0){	global $conn;	$sql="insert into ih_log(event,type) 	values('$event','$type')"; 	mysql_query($sql,$conn); }//模擬下單操作//庫存是否大于0$sql="select number from ih_store where goods_id='$goods_id' and sku_id='$sku_id'";//解鎖 此時ih_store數(shù)據(jù)中g(shù)oods_id='$goods_id' and sku_id='$sku_id' 的數(shù)據(jù)被鎖住(注3),其它事務(wù)必須等待此次事務(wù) 提交后才能執(zhí)行$rs=mysql_query($sql,$conn);$row=mysql_fetch_assoc($rs);if($row['number']>0){//高并發(fā)下會導(dǎo)致超賣	$order_sn=build_order_no();	//生成訂單 	$sql="insert into ih_order(order_sn,user_id,goods_id,sku_id,price) 	values('$order_sn','$user_id','$goods_id','$sku_id','$price')"; 	$order_rs=mysql_query($sql,$conn); 		//庫存減少	$sql="update ih_store set number=number-{$number} where sku_id='$sku_id'";	$store_rs=mysql_query($sql,$conn); 	if(mysql_affected_rows()){ 		insertLog('庫存減少成功');	}else{ 		insertLog('庫存減少失敗');	} }else{	insertLog('庫存不夠');}?>

優(yōu)化方案1:將庫存字段number字段設(shè)為unsigned,當(dāng)庫存為0時,因為字段不能為負(fù)數(shù),將會返回false

 

//庫存減少$sql="update ih_store set number=number-{$number} where sku_id='$sku_id' and number>0";$store_rs=mysql_query($sql,$conn); if(mysql_affected_rows()){ 	insertLog('庫存減少成功');}

優(yōu)化方案2:使用MySQL的事務(wù),鎖住操作的行

<?php$conn=mysql_connect("localhost","big","123456"); if(!$conn){ 	echo "connect failed"; 	exit; } mysql_select_db("big",$conn); mysql_query("set names utf8");$price=10;$user_id=1;$goods_id=1;$sku_id=11;$number=1;//生成唯一訂單號function build_order_no(){  return date('ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);}//記錄日志function insertLog($event,$type=0){	global $conn;	$sql="insert into ih_log(event,type) 	values('$event','$type')"; 	mysql_query($sql,$conn); }//模擬下單操作//庫存是否大于0mysql_query("BEGIN");	//開始事務(wù)$sql="select number from ih_store where goods_id='$goods_id' and sku_id='$sku_id' FOR UPDATE";//此時這條記錄被鎖住,其它事務(wù)必須等待此次事務(wù)提交后才能執(zhí)行$rs=mysql_query($sql,$conn);$row=mysql_fetch_assoc($rs);if($row['number']>0){	//生成訂單 	$order_sn=build_order_no();		$sql="insert into ih_order(order_sn,user_id,goods_id,sku_id,price) 	values('$order_sn','$user_id','$goods_id','$sku_id','$price')"; 	$order_rs=mysql_query($sql,$conn); 		//庫存減少	$sql="update ih_store set number=number-{$number} where sku_id='$sku_id'";	$store_rs=mysql_query($sql,$conn); 	if(mysql_affected_rows()){ 		insertLog('庫存減少成功');		mysql_query("COMMIT");//事務(wù)提交即解鎖	}else{ 		insertLog('庫存減少失敗');	}}else{	insertLog('庫存不夠');	mysql_query("ROLLBACK");}?>

優(yōu)化方案3:使用非阻塞的文件排他鎖

<?php$conn=mysql_connect("localhost","root","123456"); if(!$conn){ 	echo "connect failed"; 	exit; } mysql_select_db("big-bak",$conn); mysql_query("set names utf8");$price=10;$user_id=1;$goods_id=1;$sku_id=11;$number=1;//生成唯一訂單號function build_order_no(){  return date('ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);}//記錄日志function insertLog($event,$type=0){	global $conn;	$sql="insert into ih_log(event,type) 	values('$event','$type')"; 	mysql_query($sql,$conn); }$fp = fopen("lock.txt", "w+");if(!flock($fp,LOCK_EX | LOCK_NB)){	echo "系統(tǒng)繁忙,請稍后再試";	return;}//下單$sql="select number from ih_store where goods_id='$goods_id' and sku_id='$sku_id'";$rs=mysql_query($sql,$conn);$row=mysql_fetch_assoc($rs);if($row['number']>0){//庫存是否大于0	//模擬下單操作 	$order_sn=build_order_no();		$sql="insert into ih_order(order_sn,user_id,goods_id,sku_id,price) 	values('$order_sn','$user_id','$goods_id','$sku_id','$price')"; 	$order_rs=mysql_query($sql,$conn); 		//庫存減少	$sql="update ih_store set number=number-{$number} where sku_id='$sku_id'";	$store_rs=mysql_query($sql,$conn); 	if(mysql_affected_rows()){ 		insertLog('庫存減少成功');		flock($fp,LOCK_UN);//釋放鎖	}else{ 		insertLog('庫存減少失敗');	} }else{	insertLog('庫存不夠');}fclose($fp);

優(yōu)化方案4:使用redis隊列,因為pop操作是原子的,即使有很多用戶同時到達(dá),也是依次執(zhí)行,推薦使用(mysql事務(wù)在高并發(fā)下性能下降很厲害,文件鎖的方式也是)

先將商品庫存如隊列

 

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

搶購、描述邏輯

<?php$conn=mysql_connect("localhost","big","123456"); if(!$conn){ 	echo "connect failed"; 	exit; } mysql_select_db("big",$conn); mysql_query("set names utf8");$price=10;$user_id=1;$goods_id=1;$sku_id=11;$number=1;//生成唯一訂單號function build_order_no(){  return date('ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);}//記錄日志function insertLog($event,$type=0){	global $conn;	$sql="insert into ih_log(event,type) 	values('$event','$type')"; 	mysql_query($sql,$conn); }//模擬下單操作//下單前判斷redis隊列庫存量$redis=new Redis();$result=$redis->connect('127.0.0.1',6379);$count=$redis->lpop('goods_store');if(!$count){	insertLog('error:no store redis');	return;}//生成訂單 $order_sn=build_order_no();$sql="insert into ih_order(order_sn,user_id,goods_id,sku_id,price) values('$order_sn','$user_id','$goods_id','$sku_id','$price')"; $order_rs=mysql_query($sql,$conn); //庫存減少$sql="update ih_store set number=number-{$number} where sku_id='$sku_id'";$store_rs=mysql_query($sql,$conn); if(mysql_affected_rows()){ 	insertLog('庫存減少成功');}else{ 	insertLog('庫存減少失敗');} 

模擬5000高并發(fā)測試

webbench -c 5000 -t 60 http://192.168.1.198/big/index.php
ab -r -n 6000 -c 5000  http://192.168.1.198/big/index.php

上述只是簡單模擬高并發(fā)下的搶購,真實場景要比這復(fù)雜很多,很多注意的地方

如搶購頁面做成靜態(tài)的,通過ajax調(diào)用接口

再如上面的會導(dǎo)致一個用戶搶多個,思路:

需要一個排隊隊列和搶購結(jié)果隊列及庫存隊列。高并發(fā)情況,先將用戶進(jìn)入排隊隊列,用一個線程循環(huán)處理從排隊隊列取出一個用戶,判斷用戶是否已在搶購結(jié)果隊列,如果在,則已搶購,否則未搶購,庫存減1,寫數(shù)據(jù)庫,將用戶入結(jié)果隊列。

測試數(shù)據(jù)表

---- 數(shù)據(jù)庫: `big`---- ------------------------------------------------------------ 表的結(jié)構(gòu) `ih_goods`--CREATE TABLE IF NOT EXISTS `ih_goods` (  `goods_id` int(10) unsigned NOT NULL AUTO_INCREMENT,  `cat_id` int(11) NOT NULL,  `goods_name` varchar(255) NOT NULL,  PRIMARY KEY (`goods_id`)) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ;---- 轉(zhuǎn)存表中的數(shù)據(jù) `ih_goods`--INSERT INTO `ih_goods` (`goods_id`, `cat_id`, `goods_name`) VALUES(1, 0, '小米手機');-- ------------------------------------------------------------ 表的結(jié)構(gòu) `ih_log`--CREATE TABLE IF NOT EXISTS `ih_log` ( `id` int(11) NOT NULL AUTO_INCREMENT, `event` varchar(255) NOT NULL, `type` tinyint(4) NOT NULL DEFAULT '0', `addtime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`)) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;---- 轉(zhuǎn)存表中的數(shù)據(jù) `ih_log`---- ------------------------------------------------------------ 表的結(jié)構(gòu) `ih_order`--CREATE TABLE IF NOT EXISTS `ih_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', `price` float NOT NULL, `addtime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='訂單表' AUTO_INCREMENT=1 ;---- 轉(zhuǎn)存表中的數(shù)據(jù) `ih_order`---- ------------------------------------------------------------ 表的結(jié)構(gòu) `ih_store`--CREATE TABLE IF NOT EXISTS `ih_store` ( `id` int(11) NOT NULL AUTO_INCREMENT, `goods_id` int(11) NOT NULL, `sku_id` int(10) unsigned NOT NULL DEFAULT '0', `number` int(10) NOT NULL DEFAULT '0', `freez` int(11) NOT NULL DEFAULT '0' COMMENT '虛擬庫存', PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='庫存' AUTO_INCREMENT=2 ;---- 轉(zhuǎn)存表中的數(shù)據(jù) `ih_store`--INSERT INTO `ih_store` (`id`, `goods_id`, `sku_id`, `number`, `freez`) VALUES(1, 1, 11, 500, 0);

以上就是小編為大家?guī)淼膒hp結(jié)合redis實現(xiàn)高并發(fā)下的搶購、秒殺功能的實例全部內(nèi)容了,希望大家多多支持武林網(wǎng)~

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
蜜臀av在线观看| 亚洲综合成人网| 综合综合综合综合综合网| 在线观看国产成人av片| 亚洲视频在线观看一区二区| 国产精品免费免费| 国产传媒久久文化传媒| 麻豆精品久久精品色综合| 日本在线视频免费| 草草影院在线| 久久www人成免费看片中文| 久久夜色精品| 精品国产精品久久一区免费式| 日日草天天干| 日韩高清免费在线| 欧美黄色a视频| 九色porny丨首页在线| 久久久久久久久丰满| 亚洲综合欧美激情| 免费精品视频在线| 猛性xxxxx| 久久精品视频16| 水蜜桃在线视频| 粉嫩欧美一区二区三区| 日韩欧美激情一区二区| 福利片在线一区二区| 1024精品久久久久久久久| 国产精品一线天粉嫩av| 日本丶国产丶欧美色综合| 国产又黄又粗又猛又爽| 久久夜色精品亚洲噜噜国产mv| 国产久一道中文一区| segui88久久综合9999| 手机视频在线观看| 四虎影视精品成人| 国产欧美在线观看视频| 国产va免费精品高清在线| 久草免费在线播放| 国产一区二区三区四区二区| 国产精品高清无码| 麻豆精品免费视频| 国产精彩精品视频| 日韩网站在线观看| 91福利精品第一导航| 97色婷婷成人综合在线观看| 欧美野外猛男的大粗鳮| 韩日一区二区| 中文字幕高清20页| 日韩中文字幕免费在线观看| 国产无一区二区| 影音先锋欧美精品| 中文有码久久| 精品视频日韩| 国产精品久久久久久网站| 欧美 日韩 国产 激情| 中文字幕成人动漫| 99久久亚洲国产日韩美女| 国产精品综合久久久久| 国内视频一区二区| 国产精品19乱码一区二区三区| 国产在线视频网| chinesemodel无套啪啪| 亚洲第一页综合| 婷婷在线播放| 裸体xxxx视频在线| 久久综合999| 北条麻妃av高潮尖叫在线观看| 国产精品视频yy9299一区| 日韩一区二区三区精品视频| 性做爰过程免费播放| 一区二区三区美女| 中文一区在线观看| 黄色精品在线观看| 欧美色中文字幕| 国产伦理久久久久久妇女| 欧美一级片在线免费观看| 国产尤物在线观看| 国产成人在线视频免费观看| 国产老女人乱淫免费| 精品处破学生在线二十三| 色婷婷亚洲精品| www.夜色| 欧美77777免费视频| 日产日韩在线亚洲欧美| 性xxxxfjsxxxxx欧美| 国产做a爰片久久毛片| 亚洲AV无码久久精品国产一区| 特黄视频免费看| 午夜精品一区二区三区视频免费看| 精品成人免费自拍视频| 午夜精品一区二区在线观看| 又黄又爽毛片免费观看| 欧美激情网站在线观看| 99热在线免费观看| 精品少妇一区二区三区日产乱码| 国产精品久久亚洲7777| 成人美女视频在线观看| 中文字幕亚洲天堂| 亚洲线精品久久一区二区三区| 亚洲第一页中文字幕| 亚洲91在线| 欧美中文字幕在线播放| 国产一级一区二区| 麻豆国产精品视频| 精品乱色一区二区中文字幕| 久久久久久中文字幕| 欧美大喷水吹潮合集在线观看| 6080亚洲精品一区二区| 国产欧美大片| 美女尤物国产一区| 91麻豆swag| 亚洲精品国产一区黑色丝袜| 国产乱码精品一区二区三区av| 91麻豆产精品久久久久久| 99视频在线观看视频| 进去里视频在线观看| 97影院在线午夜| 91啦中文成人| 中文字幕不卡每日更新1区2区| 在线看日韩精品电影| 免费精品视频最新在线| 国产视频在线播放| 国产精品揄拍一区二区| 欧美激情论坛| 好看的视频你懂的| 亚洲网站在线看| 日韩在线观看网站| 国产精品7区| 亚洲人成在线观看一区二区| 欧美激情中文字幕| 成人永久免费视频| 精人妻一区二区三区| baoyu135国产精品免费| 亚洲另类春色校园小说| 国产精品无码久久久久成人app| www.xxxx日本| 亚洲第一精品在线观看| 色偷偷亚洲男人天堂| 欧美成人精品| 欧美精品九九| 新版中文字幕在线资源| 永久免费成人代码| 亚洲一区二区久久久久久| 色豆豆成人网| 国产又大又黄又粗的视频| 偷拍精品福利视频导航| 麻豆网站在线观看| 国产欧美在线一区| 国产激情无套内精对白视频| 在线看日韩欧美| 亚洲日本黄色片| a视频网址在线观看| 精品视频偷偷看在线观看| 欧美一级爱爱| 免费亚洲一区| 男人天堂手机在线观看| 日韩欧美在线观看| www.欧美免费| 欧美变态视频| 日韩av免费在线观看| 8mav模特福利视频在线观看| 色姑娘资源站| 亚洲三级电影全部在线观看高清| 国产极品在线播放| julia一区二区中文久久94| 免费一二一二在线视频| 亚洲欧洲一区二区| 97人妻一区二区精品视频| 网友自拍亚洲| 无码人妻av一区二区三区波多野| 中文字幕第2页| 91久久精品国产91久久| 久久久久久久久国产| 性欧美videosex高清少妇| 喜爱夜蒲2在线| 欧美成人三级电影在线| 国产乱国产乱老熟| 精品人伦一区二区色婷婷| 国产免费av一区二区三区| 99国产精品免费网站| 国产偷人妻精品一区| 午夜在线观看免费一区| 久操视频在线观看| 尤物视频网址| 亚洲一区中文在线| 久久久久久高潮国产精品视| 色之综合天天综合色天天棕色| 亚洲精品日韩专区silk| 欧美乱熟臀69xxxxxx| 一本大道久久精品| 国产黄色片大全| 日韩电影在线观看完整版| 色鬼7777久久| wwwwxxxx国产| 免费91麻豆精品国产自产在线观看| 成人在线分类| 在线观看国产中文字幕| 欧美午夜一区| 特级毛片在线观看| 欧美午夜精品久久久久久人妖| 久久久www免费人成黑人精品| 久久精品资源| c++连点器| 性色av无码久久一区二区三区| 99在线精品观看| 亚洲AV午夜精品| 99成人精品| 新版中文在线官网| 动漫美女无遮挡免费| 欧洲精品在线观看| 在线不卡欧美| 欧美激情综合色综合啪啪五月| 国产日韩视频一区| 91视频免费在线看| 久久国产视频播放| 97久久人国产精品婷婷| 嫩草研究院在线观看| 99热精品在线播放| 91福利小视频| 男女羞羞视频教学| 福利社在线免费视频| 国产精品视频在线免费观看| 色88久久久久高潮综合影院| 欧美熟妇精品一区二区| 天天av天天翘天天综合网| 亚洲成人精品视频在线观看| 欧美老女人在线视频| 亚洲一区二区成人在线观看| 国产成免费视频| 91日韩在线播放| 在线亚洲免费| 国产高清精品久久久久| 国产欧美日韩综合精品一区二区| 日本一区二区三区网站| 欧美国产日韩a欧美在线观看| 黄色成人免费看| 波多野结衣中文字幕在线播放| 亚洲一区在线观看网站| 久草香蕉在线| 懂色av中文字幕一区二区三区| 亚洲一级特黄毛片| www.av毛片| 午夜在线播放视频欧美| 亚洲精品国产嫩草在线观看| 欧美一区二区三区免费视频| 91香蕉视频在线播放| 欧洲在线/亚洲| 国产精品成人播放| 国产suv精品一区| 成人在线免费公开观看视频| 一区二区三区在线观看国产| 精品亚洲国产成人av制服丝袜| 肉肉视频在线观看| 99蜜月精品久久91| 精品一区二区三区不卡| 成人欧美一区二区三区黑人| 少妇欧美激情一区二区三区| 日本激情一区二区| 国产情侣自拍小视频| 蜜桃一区二区三区在线| 神马久久久久久久久| 亚洲男人的天堂一区二区| 中文字幕第六页| 久久综合88中文色鬼| 亚洲成a人片在线www| 亚洲日本成人在线观看| 九九久久久2| 精品freesex老太交| 爱爱视频网站| 日韩五码在线观看| 欧美肥老太太性生活| 亚洲精品aa| 国产资源在线观看入口av| 成人蜜臀av电影| 欧美精品中文字幕一区| www插插插无码视频网站| 精品视频一区 二区 三区| 成人久久久久久久| 99精品国产在热久久婷婷| 欧美精品日韩www.p站| 啪啪小视频网站| 国产精品视频地址| 亚洲欧美日韩三级| 美女免费观看一区二区三区| 国产精品嫩草影院俄罗斯| 欧美xxxx18国产| 欧美日韩一区二区高清| 99re热视频| 91久久久久久久久久| 免费91在线观看| 国产精品女主播一区二区三区| 欧美亚洲成人免费| 91在线|亚洲| 国产精品中文字幕久久久| 美女激情视频网站| www.com久久久| 色综合天天狠狠| 中日精品一色哟哟| 亚洲最大的免费视频网站| 国产九一精品| 777影院狠狠色| 日本女优北野望在线电影| 亚洲黄色天堂| 国产精品视频专区| 韩国精品主播一区二区在线观看| 欧美图片欧美激情欧美精品| 国模无码视频一区| gogogo高清在线观看一区二区| 波多野结衣三级视频| 中文字幕巨乱亚洲| 18成人在线观看| 欧美91看片特黄aaaa| 欧美日韩国产一区二区在线观看| 男人女人靠逼视频| 国产一区二区三区在线观看免费视频| 亚洲精品免费在线观看视频| 欧美一区二区播放| 欧美一级小视频| 精品一区二区三区视频在线观看| 久久一区二区三区喷水| 97久久综合精品久久久综合| 可以在线看的av| 国产chinese精品一区二区| 欧美性猛交xxxx免费看| 欧美激情喷水| 麻豆精品国产传媒| 欧美一级特黄高清视频| 日韩08精品|