PHP+JMeter模拟测试高并发场景。附代码。

2023-05-16

文章目录

      • 1.建表
      • 2.编写模型类和控制器
      • 3.使用jmeter模拟高并发场景
      • 4. 开始测试
      • 5. 解决办法
      • 6. 其他的测试高并发的工具

1.建表

  1. 新建商品表

    CREATE TABLE `zlsn_concurrency_goods` (
      `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
      `goods_code` varchar(10) NOT NULL COMMENT '商品编码',
      `num` int(10) NOT NULL COMMENT '商品剩余数量',
      `created_at` datetime DEFAULT CURRENT_TIMESTAMP,
      `updated_at` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COMMENT='模拟高并发-商品表';
    
  2. 新建订单表

    CREATE TABLE `zlsn_concurrency_user_order` (
      `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
      `user_code` varchar(10) NOT NULL COMMENT '用户编码',
      `order_code` varchar(10) NOT NULL COMMENT '订单编码',
      `created_at` datetime DEFAULT CURRENT_TIMESTAMP,
      `updated_at` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=114 DEFAULT CHARSET=utf8mb4 COMMENT='模拟高并发-用户订单表';
    

2.编写模型类和控制器

  1. 模型类

    <?php
    
    namespace App\Models;
    
    use Illuminate\Database\Eloquent\Model;
    
    /**
     * 测试高并发商品表
     * Class TestGoods
     * @package App\Models
     */
    class TestGoods extends Model
    {
        protected $table = "concurrency_goods";
    }
    
    <?php
    
    namespace App\Models;
    
    use Illuminate\Database\Eloquent\Model;
    
    /**
     * 测试高并发用户订单表
     * Class UserOrder
     * @package App\Models
     */
    class TestUserOrder extends Model
    {
        protected $table = "concurrency_user_order";
    }
    
  2. 控制器

    <?php
    
    namespace App\Http\Controllers\Test;
    
    use App\Models\TestGoods;
    use App\Models\TestUserOrder;
    
    /**
     * 测试高并发接口
     * Class ConcurrencyController
     * @package App\Http\Controllers\Test
     */
    class ConcurrencyController
    {
        /**
         * Notes:秒杀功能
         * Author:zlsn <269765627@qq.com>
         * DateTime: 2022/7/9 10:32
         */
        public function seckill()
        {
            $detail = TestGoods::where('id', 1)->select('id', 'num')->get()->toArray();
            //模拟存放用户id
            $ids = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
            $userId = "测试用户" . $ids[rand(0, 9)];
            if (!empty($detail) && $detail[0]['num'] > 0) {
    
                //商品id和商品数量
                $id = $detail[0]['id'];
                $number = $detail[0]['num'];
    
                //商品数量减一
                $number -= 1;
                $testGoodModel = new TestGoods();
                $param['num'] = $number;
                $testGoodModel->where('id', $id)->update($param);
                //保存到订单表
                $testUserOrderModel = new TestUserOrder();
                $testUserOrderModel->user_code = $userId;
                $testUserOrderModel->order_code = rand(111111, 999999);
                $testUserOrderModel->save();
                echo '抢购成功';
            } else {
                echo '商品数量不足';
            }
        }
    
    }
    

3.使用jmeter模拟高并发场景

jmeter依赖于jdk,需要本地配置一下。jdk配置方法

  1. 首先去下载jemter 下载链接

    1. windows下载zip或者tgz格式的都可以。解压-然后去bin目录双击jemter.bat文件,启动jemter。

    2. 右键test plan-add-Threads-Thread group (添加线程组)

    3. 再右键Thread group-add-Sampler-HTTP Request (添加http请求)

    4. 配置http请求,如图
      在这里插入图片描述

    5. 配置thread group,如图
      在这里插入图片描述

4. 开始测试

重现超卖情况以及商品数量变成负数的情况

  1. 设置商品数量初始值为10

    在这里插入图片描述

  2. 点击jemter菜单栏的start按钮,然后选择一下测试文件保存的路径即可。会发现订单表出现了超卖的情况,并且还会出现一个用户秒杀到多个商品的情况。(我这里出现了15份订单)。

    这里要说明一下为什么商品表的数量没有变成负数?

    ​ 因为秒杀方法中有对于商品数量的判断,即使最后剩余1件商品,然后同时进来了多个请求,此时它们都会把商品数量修改成0,然后再去保存到订单表。

    ​ 如果在判断内,重新获取商品数量,再去减一的话,就会出现负数。如果改成如下代码

    public function seckill()
        {
            $detail = TestGoods::where('id', 1)->select('id', 'num')->get()->toArray();
            //模拟存放用户id
            $ids = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
            $userId = "测试用户" . $ids[rand(0, 9)];
            if (!empty($detail) && $detail[0]['num'] > 0) {
    
                //商品id和商品数量
                $id = $detail[0]['id'];
    
                //商品数量减一
                //再次获取当前的商品数量,再进行减一,而不是直接用判断外获取的商品数量减一
                $data = TestGoods::where('id', 1)->select('num')->get()->toArray();
                $number = $data[0]['num'];
                $number -= 1;
                
                $testGoodModel = new TestGoods();
                $param['num'] = $number;
                $testGoodModel->where('id', $id)->update($param);
                //保存到订单表
                $testUserOrderModel = new TestUserOrder();
                $testUserOrderModel->user_code = $userId;
                $testUserOrderModel->order_code = rand(111111, 999999);
                $testUserOrderModel->save();
                echo '抢购成功';
            } else {
                echo '商品数量不足';
            }
        }
    

    在这里插入图片描述

5. 解决办法

​ 解决同一个用户秒杀多件商品的情况—添加判断(但是判断有时候未生效,还会存在一个用户抢到两件商品的情况,表示费解。。

  1. 解决方法一 悲观锁

    public function seckill()
        {
    //        $detail = TestGoods::where('id', 1)->select('id', 'num')->get()->toArray();
            DB::beginTransaction();
            $detail = DB::select("select num,id from zlsn_concurrency_goods where id = 1 for update ");
            //模拟存放用户id
            $ids = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
            $userId = "测试用户" . $ids[rand(0, 9)];
            if (!empty($detail) && $detail[0]->num > 0) {
    
                //商品id和商品数量
                $number = $detail[0]->num;
                $id = $detail[0]->id;
    
                $testUserOrderModel = new TestUserOrder();
                $check = $testUserOrderModel->where('user_code', $userId)->get()->toArray();
                //判断当前用户是否已经抢购过--这判断不一定会生效,依然可能存在一个用户购买多次的情况
                if (empty($check)) {
                    //商品数量减一
                    $number -= 1;
                    $testGoodModel = new TestGoods();
                    $param['num'] = $number;
                    $res = $testGoodModel->where('id', $id)->update($param);
    
                    if ($res) {
                        //保存到订单表
                        $testUserOrderModel->user_code = $userId;
                        $testUserOrderModel->order_code = rand(111111, 999999);
                        $testUserOrderModel->save();
                        echo '抢购成功';
                        DB::commit();
                    } else {
                        echo '商品数量修改失败';
                        DB::rollBack();
                    }
                } else {
                    echo '您已经购买过此商品';
                    DB::rollBack();
                }
            } else {
                echo '商品数量不足';
                DB::rollBack();
            }
        }
    

    在修改数据的时候,采用锁定状态,排斥外部请求的修改。遇到加锁的状态,其余请求必须等待。

    缺点:虽然可以解决线程安全的问题,但是对于高并发并不适用。对于很多没有抢到锁的请求,会陷入一直等待的状态,同时,这种请求很多的话,瞬间增大系统的平均响应时间,结果可能是数据库连接数耗尽,系统陷入异常。

  2. 解决方法二 FIFO队列思路

    FIFO(first input first output):即先进先出。这样的话就会避免有些请求永远获取不到锁的情况。但是有种将多线程强行变成单线程的感觉。就像是一条八车道的路,强行并称了单行道。

    缺点:如果使用这种情况,可能一瞬间把队列内存撑爆,然后系统陷入异常。假如设计一个超级大的内存队列,但是系统处理队列内请求的速度,根本无法和疯狂涌入队列内的数目相比。也就是说队列内的请求会越积累越多,最终web系统平均相应时长还是会增大,造成系统异常。

  3. 解决方法三 文件锁思路

    使用非阻塞的文件排他锁

    缺点:在我们对文件进行读写操作时,很有可能多个进程对进一文件进行操作,如果这时不对文件的访问进行相应的独占,就容易造成数据丢失

    public function seckill()
        {
            $fp = fopen("lock.txt", "w+");
            if (!flock($fp, LOCK_EX | LOCK_NB)) {
                echo "系统繁忙,请稍后再试";
                return;
            }
    
            $detail = TestGoods::where('id', 1)->select('id', 'num')->get()->toArray();
            //模拟存放用户id
            $ids = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
            $userId = "测试用户" . $ids[rand(0, 9)];
            if (!empty($detail) && $detail[0]['num'] > 0) {
    
                //商品id和商品数量
                $number = $detail[0]['num'];
                $id = $detail[0]['id'];
    
                $testUserOrderModel = new TestUserOrder();
                $check = $testUserOrderModel->where('user_code', $userId)->get()->toArray();
                //判断当前用户是否已经抢购过--这判断不一定会生效,依然可能存在一个用户购买多次的情况
                if (empty($check)) {
                    //商品数量减一
                    $number -= 1;
                    $testGoodModel = new TestGoods();
                    $param['num'] = $number;
                    $res = $testGoodModel->where('id', $id)->update($param);
    
                    if ($res) {
                        //保存到订单表
                        $testUserOrderModel->user_code = $userId;
                        $testUserOrderModel->order_code = rand(111111, 999999);
                        $testUserOrderModel->save();
                        echo '抢购成功';
                        flock($fp, LOCK_UN);//释放锁
                    } else {
                        echo '商品数量修改失败';
                    }
                } else {
                    echo '您已经购买过此商品';
                }
            } else {
                echo '商品数量不足';
            }
            fclose($fp);
        }
    
  4. 解决方法四 乐观锁

    在数据表中添加version字段。

    所有进来的请求都可以去修改数据,但是在修改数据之前会先获得该数据的一个版本号,修改之后如果和修改前的版本号不一致,则进行事务回滚。

    缺点:增大CPU的计算开销。

    public function seckill()
        {
            DB::beginTransaction();
            $detail = TestGoods::where('id', 1)->select('id', 'num','version')->get()->toArray();
            //模拟存放用户id
            $ids = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
            $userId = "测试用户" . $ids[rand(0, 9)];
            if (!empty($detail) && $detail[0]['num'] > 0) {
    
                //商品id和商品数量
                $number = $detail[0]['num'];
                $id = $detail[0]['id'];
                $version = $detail[0]['version'];
    
                $testUserOrderModel = new TestUserOrder();
                $check = $testUserOrderModel->where('user_code', $userId)->get()->toArray();
                //判断当前用户是否已经抢购过--这判断不一定会生效,依然可能存在一个用户购买多次的情况
                if (empty($check)) {
                    //商品数量减一
                    $number -= 1;
                    $testGoodModel = new TestGoods();
                    $param['num'] = $number;
                    $res = $testGoodModel->where('id', $id)->update($param);
                    $data = TestGoods::where('id', 1)->select('version')->get()->toArray();
                    $version_after = $data[0]['version'];
                    if($version_after != $version){
                        DB::rollBack();
                    }
                    if ($res) {
                        //保存到订单表
                        $testUserOrderModel->user_code = $userId;
                        $testUserOrderModel->order_code = rand(111111, 999999);
                        $testUserOrderModel->save();
                        echo '抢购成功';
                        DB::commit();
                    } else {
                        echo '商品数量修改失败';
                        DB::rollBack();
                    }
                } else {
                    echo '您已经购买过此商品';
                    DB::rollBack();
                }
            } else {
                echo '商品数量不足';
                DB::rollBack();
            }
        }
    
  5. Redis中的watch

    这种方法也属于乐观锁之一。(模拟了多次,其中有两次还是出现了超卖的情况,不知道是不是自己操作的问题。

    public function seckill()
        {
            $myWatchKey = Redis::get('myWatchKey'); //不需要提前set,本就是获取一个null值。如果提前set的话,那每次请求接口的时候,这个可以都是固定的值
            $number = 20;//商品数量
            if ($myWatchKey < $number) {
                Redis::watch("myWatchKey");
                Redis::multi(); //开启事务
    
                //插入抢购数据
                Redis::set("myWatchKey", $myWatchKey + 1);
    
                $rob_result = Redis::exec();//执行事务
                if ($rob_result) {
                    Redis::hSet("watchKeyList", "user_" . mt_rand(1, 9999), $myWatchKey);
                    $myWatchList = Redis::hGetAll("watchKeyList");
    
                    echo "抢购成功!<br/>";
                    echo "剩余数量:" . ($number - $myWatchKey - 1) . "<br/>";
                    echo "用户列表:<pre>";
                    var_dump($myWatchList);
                } else {
                    Redis::hSet("watchKeyList", "user_" . mt_rand(1, 9999), '没抢到');
                    echo "手气不好,再抢购!";
                    exit;
                }
            }else{
                echo '商品数量不足,抢购失败';
            }
        }
    

6. 其他的测试高并发的工具

  1. apache安装目录下的bin目录可以使用ab命令测试高并发

    [root@myhost vhost]# ab -c 10000 -n 100000 http://www.baidu.com
    -c 表示并发用户数
    -n 表示请求总数
    
  2. postman也可以测试高并发

    步骤:

    1. 新建一个collection

    2. 在collection中新建请求

    3. 点击collection,有个run按钮。可以配置请求数。如图
      在这里插入图片描述

在这里插入图片描述

  1. 同理Apifox也一样

参考链接:

​ 如何用PHP解决高并发问题?(附源码)
推荐一篇文章 PHP+Redis怎么解决商品超卖问题

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PHP+JMeter模拟测试高并发场景。附代码。 的相关文章

  • 如何在 MySQL 中使用 INET_ATON 进行通配符搜索 IP 地址?

    我发现这个方法可以使用 INET ATON 将 IP 地址作为整数存储在 MySQL 数据库中 https stackoverflow com a 5133610 4491952 https stackoverflow com a 5133
  • Symfony 4.1 组件 - 依赖注入问题

    我正在用 PHP 重构旧应用程序 我正在尝试使用 Symfony 依赖注入组件将服务注入控制器 或其他服务 但我不知道如何实现这一点 因为 symphony 文档比框架组件更适合使用框架 我已经有了自己的内核 包含所有服务和控制器的容器 控
  • PHP 中 while (true){ 是什么意思?

    我看过这段代码 但不知道这意味着什么 while true echo Hello world 我知道什么是 while 循环 但是 while true 是什么意思 会执行多少次 这不是无限循环吗 虽然是无限循环 但您可以使用以下命令退出它
  • 如何在 Api-Platform 中按链接属性过滤结果?

    我有一个User实体和一个Organisation实体 存在关系ManyToOne之间Booking and User ORM ManyToOne targetEntity App Entity User inversedBy bookin
  • CKEditor TypeError:c[a] 在 CodeIgniter 中未定义

    我正在尝试在基于 codeigniter 的网站中安装 CKEditor 并且我已按照本教程进行操作 Codeigniter 教程中的 CKEditor http nukium com developpement php framework
  • CodeIgniter:使用多维 POST 数据验证表单

    所以框架是CodeIgniter 2 0 2 我有一个表单 其中包含与数据库中的行相对应的字段组 字段名称的格式为 opt 0 foo opt 0 bar opt 1 foo opt 1 bar etc 索引 1 2等 并不对应于数据库中的
  • 通过“SELECT”命令选择每组的前两条记录的最佳方法是什么?

    例如我有下表 id group data 1 1 aaa 2 1 aaa 3 2 aaa 4 2 aaa 5 2 aaa 6 3 aaa 7 3 aaa 8 3 aaa 通过 SELECT 命令选择每组的前两条记录的最佳方法是什么 如果没有
  • php paypal 服务器端 REST 集成失败

    我无法发布代码 错误等 因为 你需要至少 10 个声誉才能发布 2 个以上的链接 并且所有内容都包含很多链接 只是花了几个小时写了一篇完整详细的帖子 我在这里 和其他地方 读过类似的帖子 但它们没有帮助 我基本上遵循 https devel
  • 表单请求中的 Laravel 数组验证

    我无法验证 Form Request 类中包含数组元素的字段 规则方法 public function rules return state gt required state 0 gt required state gt required
  • 如何在 PHP 中对数组和数据进行排序?

    这个问题旨在作为有关 PHP 中数组排序问题的参考 人们很容易认为您的特定案例是独特的并且值得提出新问题 但大多数实际上只是此页面上的解决方案之一的微小变化 如果您的问题因与此问题重复而被关闭 请仅在您能解释为什么它与以下所有问题显着不同的
  • 调用未定义的函数 MYSQL_NUM_ROWS() [重复]

    这个问题在这里已经有答案了 我正在尝试使用 php 验证登录 但收到此错误 致命错误 未捕获错误 调用 opt lampp htdocs social index php 100 中未定义的函数 MYSQL NUM ROWS 堆栈跟踪 0
  • 在 PHP $_SESSION 中存储数据不安全吗?

    根据我的理解 PHP 进程的行为并不像应用程序服务器进程 因此 执行脚本后 PHP 进程不会保留任何用户特定数据 相反 它将它们存储在用户的 cookie 中 所以无论我们存储在什么地方 SESSSION进入cookie 这是真的 如果是
  • PHP 特性 - 定义通用常量

    定义可由命名空间内的多个类使用的常量的最佳方法是什么 我试图避免过多的继承 因此扩展基类不是理想的解决方案 并且我正在努力寻找使用特征的良好解决方案 这在 PHP 5 4 中是否可行 或者应该采取不同的方法 我有以下情况 trait Bas
  • PHP:如何获取
    中的名称值

    有没有办法获取form标签中name属性的值 我正在使用 PHP 但在 中没有看到它 POST 有没有办法获取form标签中name属性的值 我正在使用 PHP 但在 POST 中没有看到它 不 表单的名称属性永远不会设置为作为 POST
  • PHP Imagick - “-量化透明”等效项

    是否有 PHP Imagick 等效项 quantize transparent 量化透明使用示例 http www imagemagick org Usage quantize color trans注意 在页面中搜索 量化透明 Quan
  • 自动安排并执行 PHP 脚本

    我编写了一个 PHP 脚本 它生成一个包含数据库中所有表的 SQL 文件 我想要做的是每天或每 n 天执行这个脚本 我读过有关 cron 作业的内容 但我使用的是 Windows 如何在服务器上自动执行脚本 您需要添加计划任务来调用 URL
  • 使用 PHP 比较两个字符串的相似度

    嘿伙计们 我想寻求一些解决方案 现在我有字典了单词 txt 这里有一些例子 happy laugh sad 我有俚语字符串 hppy 我想要搜索和匹配那个俚语字符串我的字典这意味着它将返回 happy 因为这些字符串参考 快乐 in 字典
  • 在 php 中回显 JSON 数据

    我正在尝试回显一些 JSON 数据 问题是数据包含变量 但我的代码没有将变量放入字符串中 这是我的代码 status row Status priority row Priority echo status status priority
  • PHP Soap Server:使用字符串(xml 字符串)而不是 WSDL 文件(指向它的 url)实例化

    Soap Server的PHP页面 我见过 http www php net manual en soapserver soapserver php http www php net manual en soapserver soapser
  • PHPExcel输出乱码

    我正在尝试 PHPExcel 附带的简单示例 01simple xls 我得到乱码输出 它 LibreOffice 想要导入文件 它认为字符集是西欧 DOS OS2 861 icelandic 输出是这样的

随机推荐

  • Python案例003——句子生成器

    目标 xff1a 通过用户提供的内容 xff0c 随机生成唯一的句子 提示 xff1a 以用户输入的名词 代词 形容词等作为输入 xff0c 然后将所有数据添加到句子中 xff0c 并将其组合返回 输出固定的 内容 43 用户输入的内容 c
  • 嵌入式软件工程师面试题

    1 int a 10 61 1 2 3 4 5 6 7 8 9 0 int p 61 amp a 1 则p 6 等于8 2 整数数组清零 xff1a bzero memset 3 siezof 测试变量所占地址的字节数 4 main cha
  • 国内代码仓库-码云

    相信使用github的同学会经常碰到这样的情况 xff0c 当我们从github上面下载稍微大一点的代码的时候就经常下载失败 xff0c 下载网速是非常的感人 国内从github上下载代码非常慢 xff0c 解决办法就是修改host或者vp
  • php对接支付宝Web支付-tp5.1框架

    具体流程 1 获取支付宝相关配置 2 传相关参数请求支付宝网关 订单金额 订单号等 3 支付宝请求回调地址 4 回调地址做相关业务处理 数据库增删改查之类 5 处理完成以后返回success给支付宝服务器 1 首先获取应用id和商户私钥以及
  • TX2+realsense D435i跑VSLAM--001--内核劝退篇

    想要使用tx2连接深度相机realsense D435i xff0c 没想到下载好官方自带SDK后 xff0c 说tx2的版本不满足需求 需要至少L4T28 2 1 xff0c 为什么偏偏就差这么一点版本 xff0c 然后查了查 xff0c
  • PHP对接微信支付--Native tp5框架

    这里实现的功能是 xff1a 网页上点击支付 xff0c 然后调用此方法生成二维码并且返回二维码的图片路径 xff0c 然后扫码支付 xff0c 付款成功进行回调 xff0c 在回调地址进行数据库操作 1 配置微信支付参数 微信支付参数 f
  • 微信支付退款 PHP

    应用场景 当交易发生之后一段时间内 xff0c 由于买家或者卖家的原因需要退款时 xff0c 卖家可以通过退款接口将支付款退还给买家 xff0c 微信支付将在收到退款请求并且验证成功之后 xff0c 按照退款规则将支付款按原路退到买家帐号上
  • windows+本地虚拟机搭建gitlab

    一 安装依赖软件 xff04 yum y install policycoreutils openssh server openssh clients postfix 二 设置postfix开机自启 xff0c 并启动 xff0c post
  • 使用Springboot实现简单的增删改查-超详细

    使用Springboot实现简单的增删改查 超详细 xff08 java小白 仅记录 不喜勿喷 xff09 php想转java 就想写个简单的增删改查 写惯了php 感觉java好复杂 php一般就是定义路由 xff0c 然后去控制器 xf
  • Windows下Virtual box安装centos以及virtual box的增强功能(超详细)

    Windows下Virtual box安装centos以及virtual box的增强功能 xff08 超详细 xff09 1 准备工作1 1 下载Virtual Box1 2 下载centos7镜像 2 安装virtual box3 新建
  • 使用crontab遇到的一点问题,报错/var/spool/cron : Permission denied和bash: /usr/bin/chattr: Permission denied

    问题 xff1a 在Linux服务器上设置crontab定时任务执行laravel任务调度的时候 xff0c crontab e 无法保存 会报错 var spool cron Permission denied 于是百度到是var spo
  • 服务器对接码云webhooks实现自动部署--超详细--PHP

    公司代码是放在码云上的 xff0c 每次提交代码 xff0c 都要去服务器上执行一下git pull xff0c 就很麻烦 xff0c 于是想对接一下码云的webhooks实现自动部署 本文参考链接1 xff0c 参考链接2 这里以lara
  • centos7搭建LNMP环境-编译安装&yum安装-超详细

    文章目录 0 首先建议使用docker搭建环境 链接在这 xff01 https blog csdn net handsomezls article details 116936581 1 首先了解编译安装和yum安装的区别 2 yum安装
  • Linux 下使用Docker 安装 LNMP环境以及项目搭建 超详细

    文章目录 一 安装docker二 docker安装php三 docker安装nginx四 docker安装mysql四 1 因为我项目中用到了redis xff0c 所以还需要安装redis容器 五 docker安装Jenkins六 将本地
  • 递归遍历无限极分类菜单、菜单树。(php版&&java版)

    文章目录 php版java版 php版 span class token operator lt span span class token operator span php span class token comment 定义一个数组
  • 手把手教你实现SVM算法(一)

    什么是机器学习 xff08 Machine Learning xff09 机器学习是研究计算机怎样模拟或实现人类的学习行为 xff0c 以获取新的知识或技能 xff0c 重新组织已有的知识结构使之不断改善自身的性能 它是人工智能的核心 xf
  • 详解laravel中使用mews/captcha、前后端分离

    文章目录 1 下载mews captcha2 找到config app php中的providers xff0c 添加如下代码3 找到config app php中的aliases xff0c 添加如下代码4 发布配置文件5 控制器代码6
  • 关于安装node-sass 4 报错的问题

    安装node sass 4 14 1的时候 各种报错 执行了以下命令立马成功了 cnpm install node span class token operator span sass span class token annotatio
  • 使用百度轻量服务器LS遇到的一些小问题

    文章目录 简介1 一开始没有找到自己购买的实例在哪 2 购买的时候已经选中了应用镜像 xff0c 但是在系统里并没有看到已经部署好的LNMP环境 xff1f 3 默认的lnmp环境分别安装在哪个目录下 xff1f 4 如何修改 重置默认的M
  • PHP+JMeter模拟测试高并发场景。附代码。

    文章目录 1 建表2 编写模型类和控制器3 使用jmeter模拟高并发场景4 开始测试5 解决办法6 其他的测试高并发的工具 1 建表 新建商品表 span class token keyword CREATE span span clas