ci mysql高并发_TP5秒杀高并发简单案例

转载:https://blog.csdn.net/qq_43164547/article/details/106595772

TP5秒杀高并发教程

介绍

测试环境

创建数据库和表

TP5的配置

编写代码

测试秒杀效果

总结

上一篇文章介绍了安装redis,那么这篇文章就介绍一下利用redis做一个简单高并发案例

win10 64位专业版

小皮面板

tp5.0框架

d9bcb20bd7409a98e698d2ae68f7c40e.png

先新建名字为redistest的数据库

再将sql语句导入创建数据表和插入数据

/*

Navicat Premium Data Transfer

Source Server : 本地

Source Server Type : MySQL

Source Server Version : 50726

Source Host : localhost:3306

Source Schema : redistest

Target Server Type : MySQL

Target Server Version : 50726

File Encoding : 65001

Date: 29/05/2020 14:55:19

*/

SET NAMES utf8mb4;

SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------

-- Table structure for ih_goods

-- ----------------------------

DROP TABLE IF EXISTS `ih_goods`;

CREATE TABLE `ih_goods` (

`goods_id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,

`cat_id` int(11) NOT NULL,

`goods_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,

PRIMARY KEY (`goods_id`) USING BTREE

) ENGINE = MyISAM AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

INSERT INTO `ih_goods` VALUES ('1', '0', '小米手机');

-- ----------------------------

-- Table structure for ih_log

-- ----------------------------

DROP TABLE IF EXISTS `ih_log`;

CREATE TABLE `ih_log` (

`id` int(11) NOT NULL AUTO_INCREMENT,

`event` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,

`type` tinyint(4) NOT NULL DEFAULT 0,

`addtime` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP,

PRIMARY KEY (`id`) USING BTREE

) ENGINE = MyISAM AUTO_INCREMENT = 16894 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------

-- Table structure for ih_order

-- ----------------------------

DROP TABLE IF EXISTS `ih_order`;

CREATE TABLE `ih_order` (

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

`order_sn` varchar(20) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,

`user_id` int(11) NOT NULL,

`status` tinyint(1) UNSIGNED NOT NULL DEFAULT 0,

`goods_id` int(11) NOT NULL,

`sku_id` int(11) UNSIGNED DEFAULT NULL,

`price` decimal(10, 2) DEFAULT NULL,

`addtime` int(11) UNSIGNED DEFAULT NULL,

PRIMARY KEY (`id`) USING BTREE

) ENGINE = MyISAM AUTO_INCREMENT = 2369 CHARACTER SET = utf8 COLLATE = utf8_unicode_ci ROW_FORMAT = Dynamic;

-- ----------------------------

-- Table structure for ih_store

-- ----------------------------

DROP TABLE IF EXISTS `ih_store`;

CREATE TABLE `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) UNSIGNED NOT NULL DEFAULT 0,

`freez` int(11) NOT NULL DEFAULT 0 COMMENT '虚拟库存',

PRIMARY KEY (`id`) USING BTREE

) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '库存' ROW_FORMAT = Dynamic;

INSERT INTO `ih_store` VALUES ('1', '1', '11', '1000', '0');

-- ----------------------------

-- Table structure for ih_test

-- ----------------------------

DROP TABLE IF EXISTS `ih_test`;

CREATE TABLE `ih_test` (

`id` int(11) NOT NULL AUTO_INCREMENT,

`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL,

PRIMARY KEY (`id`) USING BTREE

) ENGINE = MyISAM AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

INSERT INTO `ih_test` VALUES ('1', '张三');

INSERT INTO `ih_test` VALUES ('2', '王五');

将上面的sql语句导入或者选择redistest数据库选择视图->新建视图,把sql语句放上去再点预览进行导入

ce0da2f46f2c738938154815b28e49ba.png

先把application/config.php配置的调试打开

‘app_debug’的false改成true

然后配置数据库连接

正确配置 application/database.php里面mysql的账号密码和数据库名字

119acf76ea429dbb8fc5d654803871c9.png

namespace app\index\controller;

use think\cache\driver\Redis;

use think\Db;

class Index {

public function rudui(){

$store=1000;

$redis=new \Redis();

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

$res=$redis->llen('goods_store');

$count=$store-$res;

for($i=0;$i

$redis->lpush('goods_store',1);

}

}

public function buy () {

//下单前判断redis队列库存量

$redis=new \Redis();

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

$count=$redis->lpop('goods_store');

if(!$count){

$this->insertLog('error:no store redis');

return;

}

$price=10;

$user_id=1;

$goods_id=1;

$sku_id=11;

//生成订单

$order_sn=$this->build_order_no();

Db::table('ih_order') ->data(['order_sn'=>$order_sn,'user_id'=>$user_id,'goods_id'=>$goods_id,'sku_id'=>$sku_id,'price'=>$price,'addtime'=>time()])->insert();

$status = Db::table('ih_store')->where('sku_id', $sku_id)->setDec('number');

if($status > 0){

echo "库存减少成功";

$this->insertLog('库存减少成功');

}else{

echo "库存减少成功";

$this->insertLog('库存减少失败');

}

}

//生成唯一订单号

public function build_order_no(){

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

}

//记录日志

public function insertLog($event,$type=0){

Db::table('ih_log') ->data(['event'=>$event,'type'=>$type]) ->insert();

}

}

注意:先执行一下rudui方法 进行入列,这个后面整合的话可以初始化这个方法,因为这个入列只需要一次就好 博主这里就分开两个方法进行演示,小伙伴们可以自行进行整合优化

用apache自带的ab压力测试工具进行测试

这里模拟一万个请求5000个并发

ab -n 1000 -c http://www.redis233.com/index.php?s=/index/index/buy

1

2

33c9473de54bb5118f26a847c9e6c238.png

3f0b63dea04e2a4b3dac125873db3d6e.png

4e4bb602baddb9f969151b2098776272.png

可以看到是成功了!

上述只是简单模拟高并发下的抢购,真实场景要比这复杂很多,很多注意的地方如抢购页面做成静态的,通过ajax调用接口,再如上面的会导致一个用户抢多个,思路:需要一个排队队列和抢购结果队列及库存队列。高并发情况,先将用户进入排队队列,用一个线程循环处理从排队队列取出一个用户,判断用户是否已在抢购结果队列,如果在,则已抢购,否则未抢购,库存减1,写数据库,将用户入结果队列。

Linux系统的小伙伴可参考这个教程

Linux系统秒杀教程

资料代码下载 demo下载

参考链接

nginx环境下TP5隐藏index.php

PHP和Redis实现在高并发下的抢购及秒杀功能示例详解

高并发下,php与redis实现的抢购、秒杀功能

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值