PHP集成RabbitMQ开发(二)

836 阅读3分钟

RabbitMQ的简单应用 Hello World

介绍

RabbitMQ是一个消息代理。它的核心原理非常简单:接收和发送消息。你可以把它想像成一个邮局;你把信件放入信箱,邮递员把信件投递给收件人.

在理解RabbitMQ工作原理之前,先理解几个名词

  • 生产(Producing)

    发送消息的应用程序一般被称作生产者(producer);

  • 队列(queue)

    队列是一个存储消息的仓库.多个生产者可以向同一个队列发送消息,同样多个消费者也可以从同一个队列中获取数据.

  • 消费(consuming)

    获取数据并处理数据.处理消息的应用程序成为消费者(consumer);

生产者、消费者、还有代理可以不在一个主机上,在实际应用场景中也是这样应用的.

示例代码基于YII2演示.

利用php-amqplib实现消息传递的Hello World

  1. 创建消息发送方

    创建消息发送应用文件MqSendController.php

    <?php
    /**
     * User: Troy
     * Date: 2020/4/27
     * Time: 2:38 下午
     */
    namespace console\controllers;
    
    use PhpAmqpLib\Connection\AMQPStreamConnection;
    use PhpAmqpLib\Message\AMQPMessage;
    /**
     * rabbitmq 生产者
     * @package console\controllers
     */
    class MqSendController extends \yii\console\Controller
    {
        /**
         * hello world 简单队列示例
         *
         * @throws \Exception
         * @author Chuang
         */
        public function actionBaseSend()
        {
            // 创建链接
            $connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
            // 创建通道
            $channel = $connection->channel();
            // 创建队列
    //        $channel->queue_declare('hello', false, false, false, false);
            $channel->queue_declare('hello-2', false, false, false, false);
            // 设置发送消息
            $msg = new AMQPMessage('Hello World 2!');
            // 设置默认路由,在默认路由的情况下,routing_key就是队列名.
            // 将消息发送到hello 队列
    //        $channel->basic_publish($msg, '', 'hello');
            $channel->basic_publish($msg, '', 'hello-2');
    
    
            echo " [x] Sent 'Hello World!'\n";
    
            // 关闭链接
            $channel->close();
            $connection->close();
        }
    }
    

    控制台执行脚本

     ./yii  mq-send/base-send
    

    image-20200427150513902

    查看rabbitMQ管理控制台,会显示存在一条消息记录

    QQ20200427-145654@2x

    ​ 查看Queues标签,会发现存在一个hello的队列

    QQ20200427-145742@2x

    ​ 修改队列名称为hello-2,重复执行脚本后,观察控制台

    image-20200427150208887

    ​ 并且队列标签也多出一个hello-2的队列

    QQ20200427-150123@2x

    发送消息成功

  2. 创建消费方

    链接RabbitMQ服务端和创建一个通道,声明一个监听的队列,这里监听的队列名称需要和生产者的队列保持一致.

    请注意,在消费者中声明的队列。因为可能会在生产者之前,消费者和生产者的启动顺序无法保证,所以我们希望在尝试消费它的消息之前先确保队列的存在。

    创建消费者脚本MqConsumerController

    <?php
    /**
     * User: Troy
     * Date: 2020/4/27
     * Time: 3:13 下午
     */
    namespace console\controllers;
    
    use PhpAmqpLib\Connection\AMQPStreamConnection;
    
    /**
     * RabbitMq消费者示例
     * 
     * @package console\controllers
     */
    class MqConsumerController extends \yii\console\Controller
    {
        /**
         * 消费者
         * 
         * @throws \ErrorException
         * @author Chuang
         */
        public function actionConsumer()
        {
            // 创建链接
            $connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
            // 创建通道
            $channel = $connection->channel();
            // 创建队列
    //        $channel->queue_declare('hello', false, false, false, false);
            $channel->queue_declare('hello-2', false, false, false, false);
    
            echo " [*] Waiting for messages. To exit press CTRL+C\n";
    
            // 回调函数
            $callback = function ($msg) {
                echo ' [x] Received ', $msg->body, "\n";
            };
    
            // 开启一个队列消费者,指定监听的队列和回调函数
            $channel->basic_consume('hello-2', '', false, true, false, false, $callback);
    
            // 当没有消息到达时,进程会阻塞等待
            while ($channel->is_consuming()) {
                $channel->wait();
            }
    
            $channel->close();
            $connection->close();
        }
    }
    

    首先启动消费者,重复执行生产者.

    执行效果

    ![Apr-27-2020 16-19-06-2](troy-pub.yanzinet.cn/typora/Apr-… 16-19-06-2.gif)

    到这里基础的rabbitmq的hello world示例就结束了