您的位置:首页 > 数据库 > Redis

php+redis实现高并发模拟下单、秒杀、抢购操作

2017-05-03 10:10 387 查看
对于高并发下的场景,一般都是采用redis缓存机制来处理。

当然也不是只有redis可以处理、还有利用mysql事务操作锁住操作的行、文件锁。

不过这些方式都没有redis缓存高效、可靠。

模拟的过程:

首先将商品库存,存储到redis当中。

使用redis队列、来实现相应的操作。

<?php
$store = 500;//模拟库存
$redis = new Redis();
$result = $redis->connect('127.0.0.1',6379);
$res = $redis->llen('goods_store');
echo $res."<br/>";
$count = $store - $res;
for($i=0;$i<$count;$i++){
$redis->lpush('goods_store',1);//入队列一个商品
}
echo $redis->llen('goods_store');
?>


下单过程:

<?php
header("Content-Type:text/html;charset=utf-8");

$conn = mysql_connect("192.168.139.136","root","1234");
if(!$conn){
echo "数据库连接失败";exit();
}
mysql_select_db("shop",$conn);
mysql_query("set names utf8");

//生成唯一订单号
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 `shop_log`(`event`,`type`) VALUES('{$event}',{$type})";
//echo $sql;
mysql_query($sql,$conn);
}

//模拟场景
$price = 10;
$user_id = 1;
$goods_id = 1;
$sku_id = 11;
$number = 1;

//模拟下单操作
//下单时判断redis队列库存量
$redis = new Redis();
$result = $redis->connect("127.0.0.1",6379);
$count = $redis->lpop("goods_store");//下单一次、队列中弹出一个商品
if(!$count){
insertLog("redis中没有库存");
return;
}

$order_sn=build_order_no();
//生成订单
$sql="INSERT INTO `shop_order`(`order_sn`,`user_id`,`goods_id`,`sku_id`,`price`) VALUES({$order_sn},{$user_id},{$goods_id},{$sku_id},{$price})";
$order_res=mysql_query($sql,$conn);

//库存减少
$sql="UPDATE `shop_store` SET `number` = number - {$number} WHERE `sku_id` = {$sku_id}";
$store_res=mysql_query($sql,$conn);
if(mysql_affected_rows()){
insertLog('库存减少成功');
}else{
insertLog('库存减少失败');
}
?>


模拟的数据表:

/*
Navicat MySQL Data Transfer

Source Server         : centos(1)
Source Server Version : 50552
Source Host           : 192.168.139.136:3306
Source Database       : shop

Target Server Type    : MYSQL
Target Server Version : 50552
File Encoding         : 65001

Date: 2017-05-03 10:08:23
*/

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for shop_goods
-- ----------------------------
DROP TABLE IF EXISTS `shop_goods`;
CREATE TABLE `shop_goods` (
`goods_id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '商品ID',
`cat_id` int(11) NOT NULL COMMENT '商品分类ID',
`goods_name` varchar(255) NOT NULL COMMENT '商品名称',
PRIMARY KEY (`goods_id`)
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='@商品表';

-- ----------------------------
-- Records of shop_goods
-- ----------------------------
INSERT INTO `shop_goods` VALUES ('1', '0', '小米手机');

-- ----------------------------
-- Table structure for shop_log
-- ----------------------------
DROP TABLE IF EXISTS `shop_log`;
CREATE TABLE `shop_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 AUTO_INCREMENT=91602 DEFAULT CHARSET=utf8 COMMENT='@日志表';

-- ----------------------------
-- Records of shop_log
-- ----------------------------

-- ----------------------------
-- Table structure for shop_order
-- ----------------------------
DROP TABLE IF EXISTS `shop_order`;
CREATE TABLE `shop_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 AUTO_INCREMENT=2022 DEFAULT CHARSET=utf8 COMMENT='@订单表';

-- ----------------------------
-- Records of shop_order
-- ----------------------------

-- ----------------------------
-- Table structure for shop_store
-- ----------------------------
DROP TABLE IF EXISTS `shop_store`;
CREATE TABLE `shop_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) unsigned NOT NULL DEFAULT '0',
`freez` int(11) NOT NULL DEFAULT '0' COMMENT '虚拟库存',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='@库存';

-- ----------------------------
-- Records of shop_store
-- ----------------------------
INSERT INTO `shop_store` VALUES ('1', '1', '11', '0', '0');


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: