TypechoJoeTheme

Dcr163的博客

统计

thinkphp原生插入和使用rabbitmq插入返回前端时间对比

2022-02-26
/
0 评论
/
1,061 阅读
/
正在检测是否收录...
02/26

thinkphp原生插入和使用rabbitmq插入返回前端时间对比

测试内容: 批量插入400条数据

环境如下:

  • Thinkphp5.1
  • 搭建好的一台RabbitMQ,安装方法:https://www.cnblogs.com/fengyumeng/p/11133924.html;安装好后,先新建一个新用户:admin ,密码为:123456;再新建一个 Virtual Host,名称为 dcr163。也可以根据自己的需要新建其他名称,然后修改源码。
  • LNMP或LAMP环境
  • 数据库信息根据自己的环境配置
  • thinkphp 路由文件route/route里添加 `
    Route::group('rabbit',[

    Route::get('rabbit','rabbitmq/index')

    ]);`

下面是两个数据表

CREATE TABLE `transfer` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `money` decimal(10,2) NOT NULL DEFAULT '0.00',
  `from_name` varchar(20) NOT NULL DEFAULT '',
  `to_name` varchar(20) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT '事件记录表';

CREATE TABLE `transfer_logs` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `money` decimal(10,2) NOT NULL DEFAULT '0.00',
  `from_name` varchar(20) NOT NULL DEFAULT '',
  `to_name` varchar(20) NOT NULL DEFAULT '',
  `msg` varchar(200) NOT NULL DEFAULT '',
  `datetime` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8  COMMENT '消息通知表';

thinkph安装rabbitmq

进入Thinkphp项目的根目录,先composer安装Rabbitmq扩展,安装命令:composer require php-amqplib/php-amqplib

新建测试的控制器 /application/index/controller/Rabbitmq.php

代码如下

<?php

namespace app\index\controller;

use think\Controller;
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;
use think\Db;

class Rabbitmq extends Controller
{
    //首页测试
    public function index()
    {

        //统计脚本开始事件
        list($usec, $sec) = explode(" ", microtime());
        $stime    = $sec + $usec;
        $isRabbit = input('rabbit/d');

        //模拟用户提交的事件
        $datas = [
            'money'     => 200,
            'from_name' => 'user1',
            'to_name'   => 'user2'
        ];
        $db    = db('transfer');
        $id    = $db->insertGetId($datas);
        if (!$id) exit('插入失败');

        $dayTime = date('Y-m-d H:i:s');
        $db      = Db::table('transfer_logs');
        for ($i = 1; $i <= 200; $i++) {
            $sendData1 = [
                'from_name' => 'user1',
                'to_name'   => 'user2',
                'msg'       => '转出成功A-' . $i,
                'datetime'  => $dayTime
            ];
            $sendData2 = [
                'from_name' => 'user1',
                'to_name'   => 'user2',
                'msg'       => '接受成功B-' . $i,
                'datetime'  => $dayTime
            ];
            //使用Rabbit
            if ($isRabbit) {
                $this->sendRabbitmq(json_encode($sendData1));
                $this->sendRabbitmq(json_encode($sendData2));
                continue;
            }
            $db->insertAll([$sendData1, $sendData2]);
        }
        //统计脚本结束事件
        list($usec, $sec) = explode(" ", microtime());
        $etime = $sec + $usec;
        echo '<h2>' . ($isRabbit ? '使用Rabbit' : '未使用Rabbit') . ' 插入成功,费时间:' . ($etime - $stime) . 's</h2>';
    }
    /**
     * 发送到rabbitmq 消息队列
     * @param $datas
     * @return string
     * @throws \Exception
     */
    protected function sendRabbitmq($datas)
    {
        //虚拟主机 这里可以写到配置文件
        $vhost = 'dcr163';
        //队列名称
        $queueName = 'transfer';
        //链接信息,可以放到配置文件里
        $connection = new AMQPStreamConnection('192.168.254.132', '5672', 'admin', '123456', $vhost);
        $channel    = $connection->channel();
        $channel->queue_declare($queueName, false, true, false, false);
        $msg = new AMQPMessage($datas, AMQPMessage::DELIVERY_MODE_PERSISTENT);
        $channel->basic_publish($msg, '', $queueName);
        $channel->close();
        $connection->close();
    }
}

创建项目自定义命令类文件指令 /application/command/Rabbitmq.php

这个文件功能的功能是,类似开启一个常驻进程监听,代码如下:

<?php

namespace app\command;

use think\console\Command;
use think\console\Input;
use think\console\Output;
use PhpAmqpLib\Connection\AMQPStreamConnection;
use think\Db;

class Rabbitmq extends Command
{
    protected function configure()
    {
        // 指令配置
        $this->setName('rabbitmq');
        // 设置参数
    }

    protected function execute(Input $input, Output $output)
    {
        // 指令输出
        $output->writeln('rabbitmq');
        //虚拟主机
        $vhost = 'dcr163';
        //队列名称
        $queueName = 'transfer';
        //链接rabbitmq
        $connection = new AMQPStreamConnection('192.168.254.132', '5672', 'admin', '123456', $vhost);
        //获取一个通道
        $channel = $connection->channel();
        //声明队列,
        $channel->queue_declare($queueName, false, true, false, false);
        $channel->basic_qos(null, 1, null);
        //消费队列里的消息
        $channel->basic_consume($queueName, '', false, false, false, false, function ($msg) {
            //控制台打印数据,调试使用,线上使用请删除
            echo $msg->body . "\n";
            $data = json_decode($msg->body, true);
            $this->sendMsg($data);
            $msg->ack();
        });
        //监听队列里的消息
        while ($channel->is_open()) {
            $channel->wait();
        }
        $channel->close();
        $connection->close();
    }
    //处理队列里的消息
    protected function sendMsg($datas)
    {
        Db::table('transfer_logs')->insert($datas);
    }
}

测试之前,请自己手动测试和Rabbitmq的链接状态,这里可以不使用监听

先在项目根目录运行这个 think 指令

运行命令:php think rabbitmq,可以看到,已经运行了监听了,打印了rabbitmq是因为我们代码上有一行$output->writeln('rabbitmq'); 输出的语句。这里我们开启两个终端进行监听,相当与 1对多 的消费模式

测试使用即时的数据库插入和使用Rabbitmq插入数据库

不使用 Rabbitmq,访问项目:http://yourdomain/rabbit?rabbit=0

同时插入400条数据看看执行时间:

这里花费了 7.375s 的时间

使用 Rabbitmq 队列插入数据,访问项目:http://yourdomain/rabbit?rabbit=1

同时插入400条数据看看执行时间:

thinkphp 的监听数据,就是我们刚刚执行php think rabbitmq的进程状态,发现两个进程都同时处理了数据

这里花费了 5.0050001144409s 的时间

总结

可以看到 使用Tabbitmq 进行数据处理的时候,会减少和前台交互的时间,在很多中大型项目中都会使用到这类的中间件

使用Rabbitmq的逻辑就是,程序先把数据发送到 Rabbitmq 这个中间件,然后 监听进程就不断从 Rabbitmq里面读取数据处理。

rabbitmq
朗读
赞(0)
版权属于:

Dcr163的博客

本文链接:

https://dcr163.cn/625.html(转载时请注明本文出处及文章链接)

评论 (0)

人生倒计时

今日已经过去小时
这周已经过去
本月已经过去
今年已经过去个月

最新回复

  1. William Tardent
    2024-02-27
  2. Maryann Hamer
    2024-02-27
  3. Sanora Pantano
    2024-02-24
  4. aa
    2024-02-21
  5. Kassie Baum
    2024-01-28

标签云