php+redis实现高并发模拟下单、秒杀、抢购操作
对于高并发下的场景,一般都是采用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');
php+redis实现高并发模拟下单、秒杀、抢购操作的更多相关文章
- php结合redis实现高并发下的抢购、秒杀功能
抢购.秒杀是如今很常见的一个应用场景,主要需要解决的问题有两个:1 高并发对数据库产生的压力2 竞争状态下如何解决库存的正确减少("超卖"问题)对于第一个问题,已经很容易想到用缓存 ...
- php结合redis实现高并发下的抢购、秒杀功能 (转载)
抢购.秒杀是如今很常见的一个应用场景,主要需要解决的问题有两个: 1 高并发对数据库产生的压力 2 竞争状态下如何解决库存的正确减少("超卖"问题) 对于第一个问题,已经很容易想到 ...
- php 结合redis实现高并发下的抢购、秒杀功能
抢购.秒杀是如今很常见的一个应用场景,主要需要解决的问题有两个:1 高并发对数据库产生的压力2 竞争状态下如何解决库存的正确减少("超卖"问题)对于第一个问题,已经很容易想到用缓存 ...
- php结合redis实现高并发下的抢购、秒杀功能【转】
抢购.秒杀是如今很常见的一个应用场景,主要需要解决的问题有两个:1 高并发对数据库产生的压力2 竞争状态下如何解决库存的正确减少("超卖"问题)对于第一个问题,已经很容易想到用缓存 ...
- php结合redis实现高并发下的抢购、秒杀功能 (转)
抢购.秒杀是如今很常见的一个应用场景,主要需要解决的问题有两个: 1 高并发对数据库产生的压力 2 竞争状态下如何解决库存的正确减少("超卖"问题) 对于第一个问题,已经很容易 ...
- (高级篇)php结合redis实现高并发下的抢购、秒杀功能
抢购.秒杀是如今很常见的一个应用场景,主要需要解决的问题有两个:1 高并发对数据库产生的压力2 竞争状态下如何解决库存的正确减少("超卖"问题)对于第一个问题,已经很容易想到用缓存 ...
- redis实现高并发下的抢购/秒杀功能
之前写过一篇文章,高并发的解决思路(点此进入查看),今天再次抽空整理下实际场景中的具体代码逻辑实现吧:抢购/秒杀是如今很常见的一个应用场景,那么高并发竞争下如何解决超抢(或超卖库存不足为负数的问题)呢 ...
- 【转】php结合redis实现高并发下的抢购、秒杀功能
抢购.秒杀是如今很常见的一个应用场景,主要需要解决的问题有两个:1 高并发对数据库产生的压力2 竞争状态下如何解决库存的正确减少("超卖"问题)对于第一个问题,已经很容易想到用缓存 ...
- Redis实现高并发下的抢购、秒杀功能
博主最近在项目中遇到了抢购问题!现在分享下.抢购.秒杀是如今很常见的一个应用场景,主要需要解决的问题有两个:1 高并发对数据库产生的压力2 竞争状态下如何解决库存的正确减少("超卖" ...
随机推荐
- 【BZOJ2626】JZPFAR kd-tree+堆
[BZOJ2626]JZPFAR Description 平面上有n个点.现在有m次询问,每次给定一个点(px, py)和一个整数k,输出n个点中离(px, py)的距离第k大的点的标号.如果有两个( ...
- EasyNVR H5流媒体服务器方案架构设计之视频能力平台
历经过程 阶段一:经历过传统安防开发过程的开发者都有一种感觉,就是各种业务交织,各个模块的开发扯皮,各种数据库连接冲突,这很让开发工作效率很低,而且会给整体的开发带来负面影响,更重要的是,耦合度太高, ...
- jquery获取form表单中的内容,并将表单内容更新到datagrid的一行
//执行不刷新页面更新所修改的行 var arr = $('#patient_form').serializeArray();//将表单中的数据格式化成数组 var m = new Array(); ...
- c#中多线程写DataGridView出现滚动栏导致程序卡死(无响应)的解决的方法
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/u013529927/article/details/24225567 由于写的程序涉及到多线程维护一 ...
- 如何使用ipv6
需要系统至少是Vista以上还有就是要问你们学校是否已经支持IPV6 从Windows Vista开始,IPv6在默认状态下已经安装并启用,无需额外配置.检测步骤开启浏览器窗口,输入以下域名访问本站首 ...
- event loop笔记
注意四个对象: 主进程 执行栈 异步进程 任务队列 1.主进程读取js代码,形成对应的堆和执行栈(此时在同步环境) 2.当遇见异步任务,转交给异步进程进行处理 3.异步任务完成,将其推入任务队列 4. ...
- openocd+jlink为mini2440调试u-boot
需要安装openocd,如果已经安装了系统默认的openocd(默认是0.5.0,版本太低),需要先卸载掉. 在安装前需要安装必需的一些库文件: -dev libusb-1.0-0 automake ...
- ansible mysql模块的使用今年
摘自: https://www.ibm.com/developerworks/cn/linux/1502_lih_ansible/
- React之jsx语法特性
jsx 语法,直接可以在js中使用html标签. 还可以通过花括号的形式,在html标签中,写js表达式. <div> { 1 + 2 } hello,world! </div> ...
- hdu-5813 Elegant Construction(贪心)
题目链接: Elegant Construction Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (J ...