tp5使用rabbitmq

1、composer require php-amqplib/php-amqplib
2、生产者:
在这里插入图片描述

<?php
 
namespace app\common\controller;
 
use think\facade\Config;
//引入rabbitMq所需类
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;

 
class MqProducer
{
    
    /**
     * 生产者
     * @param $data 控制器传来的数据
     * @param $name 配置文件下rabbitmq文件前缀名
     * @throws \Exception
     */
    public function publish($data, $name)
    {
        //获取rabbitMq配置(刚刚在config文件下配置的rabbitmq信息)
        $amqp = Config::get('rabbitmq.AMQP');
        $amqpDefail = Config::get('rabbitmq.' . $name . '_queue');
 
        //建立连接
        $connection = new AMQPStreamConnection(
            $amqp['host'],
            $amqp['port'],
            $amqp['username'],
            $amqp['password'],
            $amqp['vhost']
        );
 
        //建立通道
        $channel = $connection->channel();
 
        //初始化交换机  
        $channel->exchange_declare($amqpDefail['exchange_name'], $amqpDefail['exchange_type'], false, true, false);
 
        //初始化队列
        $channel->queue_declare($amqpDefail['queue_name'], false, true, false, false);
 
        //绑定队列到交换机
        $channel->queue_bind($amqpDefail['queue_name'], $amqpDefail['exchange_name'], $amqpDefail['route_key']);
        
        //生成消息(json格式传输)
        $msg = new AMQPMessage(json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
 
        //推送消息到交换机
        $channel->basic_publish($msg, $amqpDefail['exchange_name'], $amqpDefail['route_key']);
 
        //关闭通道
        $channel->close();
 
        //断开连接
        $connection->close();
    }
}

3、消费者

<?php
 
namespace app\common\controller;
 
 
use think\facade\Config;
use think\facade\Log;
//引入rabbitMq所需类
use PhpAmqpLib\Message\AMQPMessage;
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Exchange\AMQPExchangeType;

class MqConsumer
{
    
    /**
     * 消费者(路由模式)
     * @param $name 配置文件下rabbitmq文件前缀名
     * @throws \ErrorException
     */
    public function consumer($name)
    {
        //获取rabbitMq配置
        $amqp = Config::get('rabbitmq.AMQP');
        $amqpDefail = Config::get('rabbitmq.' . $name . '_queue');
 
        //建立连接
        $connection = new AMQPStreamConnection(
            $amqp['host'],
            $amqp['port'],
            $amqp['username'],
            $amqp['password'],
            $amqp['vhost']
        );
 
        //建立通道
        $channel = $connection->channel();
 
        //流量控制(也被称为公平调度,这里设置一个消费者一次只处理200条消息)
        $channel->basic_qos(null, 200, null);
 
        //初始化交换机
        $channel->exchange_declare($amqpDefail['exchange_name'], $amqpDefail['exchange_type'], false, true, false);
 
        //初始化队列
        $channel->queue_declare($amqpDefail['queue_name'], false, true, false, false);
 
        //绑定队列与交换机
        $channel->queue_bind($amqpDefail['queue_name'], $amqpDefail['exchange_name'], $amqpDefail['route_key']);
        
        //消费消息
        $channel->basic_consume($amqpDefail['queue_name'], $amqpDefail['consumer_tag'], false, false, false, false, [$this, 'callback']);
        
        //注册退出函数行为(其实用不到,因为要保证消费者一直运行,所以不能断开连接))
        // register_shutdown_function([$this,'shutdown'], $channel, $connection);
 
        //消息未处理完毕时,循环监听并一直处理上方callback方法的逻辑
        $channel->consume();
 
    }
    
    /**
     * 回调后消息处理(业务逻辑放置此处)
     * @param  $msg
     */
    public function callback($msg)
    {
        //$msg->body  通过消费者传来的控制器接收的数据
        //$data = json_decode($msg->body,true);//拿到数据
        $data = $msg->body;
        Log::write('日志记录'.$data,'error');
        //Log::write('日志记录'.$data,'error');
        
        //如果有个值是quit,则让该消费者停止消费
        /*if($data['aa'] == 'quit'){
            $msg->getChannel()->basic_cancel($msg->getConsumerTag());
        }*/
        $msg->ack();  //消息应答:这波200条消息处理完毕后进行消息确认,告诉mq可以开始发下一波200条消息了
    }
 
    
    
    /**
     * @param $channel 信道
     * @param \PhpAmqpLib\Connection\AbstractConnection $connection
     */
    function shutdown($channel, $connection)
    {
        $channel->close(); //关闭通道
        $connection->close(); //断开连接
    }
 
 
}

4、配置文件
在config下新增rabbitmq.php

<?php
// +----------------------------------------------------------------------
// | rabbitMQ 示例配置
// 
//   Exchange在定义的时候是有类型的,以决定到底是哪些Queue符合条件,可以接收消息:
//                      fanout:所有bind到此exchange的queue都可以接收消息
//                      direct:通过routingKey和exchange决定的那个唯一的queue可以接收消息
//                      topic:所有符合routingKey(此时可以是一个表达式)的routingKey所bind的queue可以接收消息
//                      headers:通过headers 来决定把消息发给哪些queue(这个很少用)
// +----------------------------------------------------------------------
return [
    // 连接信息
    'AMQP' => [
        'host'     => '127.0.0.1',
        'port'     => '5672',
        'username' => 'admin',
        'password' => 'password',
        'vhost'    => '/order'
    ],
    
    //测试队列:direct 路由模式
    'test_queue' => [
        'exchange_name' => 'obs.direct',    //交换机名称
        'exchange_type' => 'direct',            //交换机运行模式(从上面四种模式中选)
        'queue_name'    => 'obs.queue',       //队列名称
        'route_key'     => 'obs.send',             //路由键,用于绑定队列与交换机
        'consumer_tag'  => ''              //消费标签
    ],
 
 
    //订单队列:direct 路由模式
    'order_queue' => [
        'exchange_name' => 'order_exchange',    //交换机名称
        'exchange_type' => 'direct',            //交换机运行模式(从上面四种模式中选)
        'queue_name'    => 'order_queue',       //队列名称
        'route_key'     => 'order',             //路由键,用于绑定队列与交换机
        'consumer_tag'  => 'order'              //消费标签
    ],
    
 
    //...等等其它队列
];

创建命令守护进程:

php think make:command Order order

在创建命令内容里,加入消费行为

<?php

namespace app\command;

use think\console\Command;
use think\console\Input;
use think\console\Output;
use app\common\controller\MqConsumer;

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

    protected function execute(Input $input, Output $output)
    {
    	// 指令输出
    	$output->writeln('order消息队列启动。。。。');
    	(new MqConsumer)->consumer('order');
    }
}

创建一个普通的控制器,来触发生产行为

<?php
namespace app\index\controller;
use app\common\controller\MqProducer;
class Index
{

    public function hello()
    {
        
        $page = input('get.page') ? input('get.page') : 1;//得到初始页码
         $data = [
                'page' => $page,  //当前页
         ];
         if($page <= 10){  //当前不是第10页则一直调用刚刚定义的生产者publish去生产消息
             (new MqProducer)->publish($data, 'order');
         }
         
         return json([
            'code' => 200,
            'msg' => 'order队列推送成功'
         ]);
    }
}

运行生产者:
nohup php think order > /dev/null 2>&1 &

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值