PHP+Laravel框架RabbitMQ简单使用(Pub/Sub模式)

简介: 一、简介publish-and- subscribe, 即发布订阅模型。在Pub/Sub模型中,生产者将消息发布到一个主题(Topic)中,订阅了该Topic的所有下游消费者,都可以接收到这条消息。特点:每个消息可以有多个订阅者;客户端只有订阅后才能接收到消息;持久订阅和非持久订阅。注意:发布者和订阅者有时间依赖:接受者和发布者只有建立订阅关系才能收到消息;持久订阅:订阅关系建立后,消息就不会消失,不管订阅者是否都在线;非持久订阅:订阅者为了接受消息,必须一直在线。 当只有一个订阅者时约等于点对点模式

一、简介


publish-and- subscribe, 即发布订阅模型。在Pub/Sub模型中,生产者将消息发布到一个主题(Topic)中,订阅了该Topic的所有下游消费者,都可以接收到这条消息。


特点:

  1. 每个消息可以有多个订阅者;
  2. 客户端只有订阅后才能接收到消息;
  3. 持久订阅和非持久订阅。


注意:

  1. 发布者和订阅者有时间依赖:接受者和发布者只有建立订阅关系才能收到消息;
  2. 持久订阅:订阅关系建立后,消息就不会消失,不管订阅者是否都在线;
  3. 非持久订阅:订阅者为了接受消息,必须一直在线。 当只有一个订阅者时约等于点对点模式


网络异常,图片无法展示
|

P 表示为生产者、 X 表示交换机、C1与C2 表示为消费者,红色表示队列。

通常情况下,一个条消息只要被消费一次就行了,那么什么情况下需要所有的消费者都对这条消息进行消费呢?最典型的情况就是需要在内存中对数据进行缓存,并需要实时进行更新。


例如,笔者做过一个违禁词系统,对用户输入的评论内容进行违禁词汇检测。这个违禁词系统,部署了在N台服务器上,为了提升检测性能,每台机器都会将违禁词库全量加载到内存中,词库的更新,是通过发送MQ消息来完成的。由于采用Pub/Sub模型,每台机器的consumer,都可以接收到这条消息,直接在内存中更新敏感词库即可。

我们现在希望将消息发布到我们的日志交换而不是无名的交换(emit_log.php)


二、使用Laravel的command来实现消息的生产和消费


发布者我们现在希望将消息发布到我们的日志交换而不是无名的交换 RabbitmqProducerCommand下的publish方法


<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
//引入amqp扩展
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;
class RabbitmqProducerCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'rabbitmq_producer';//给生产者起个command名称
    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command description';
    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }
    /**
     * Execute the console command.
     *  生产者消息代码
     * @return int
     */
    public function handle()
    {
        $this->publish();
    }
    /**
     * 发布订阅模式的发布操作
     * publish-and- subscribe, 即发布订阅模型。在Pub/Sub模型中,生产者将消息发布到一个主题(Topic)中,订阅了该Topic的所有下游消费者,都可以接收到这条消息。
     * Author: 李硕
     * Date: 2022/5/7
     * Time: 11:03
     */
    public function publish()
    {
        $connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
        $channel = $connection->channel();
        //发布模式(fanout)
        $channel->exchange_declare('logs', 'fanout', false, false, false);
        $argv = [];
        $data = implode(' ', array_slice($argv, 1));
        if (empty($data)) {
            $data = "info: 我是发布者生产的消息消息!";
        }
        $msg = new AMQPMessage($data);
        $channel->basic_publish($msg, 'logs');
        echo ' [x] Sent ', $data, "\n";
        $channel->close();
        $connection->close();
    }
}
复制代码


订阅者RabbitmqProducerCommand下的subscribe方法


<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;
class RabbitmqConsumerCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'rabbitmq_consumer';//给消费者起个command名称
    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command description';
    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }
    /**
     * Execute the console command.
     * @return int
     */
    public function handle()
    {
        $this->subscribe();
    }
    /**
     * 发布订阅模式 -订阅
     * publish-and- subscribe, 即发布订阅模型。在Pub/Sub模型中,生产者将消息发布到一个主题(Topic)中,订阅了该Topic的所有下游消费者,都可以接收到这条消息。
     * Author: 李硕
     * Date: 2022/5/7
     * Time: 11:03
     */
    public function subscribe()
    {
        $connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
        $channel = $connection->channel();
        $channel->exchange_declare('logs', 'fanout', false, false, false);
        list($queue_name, ,) = $channel->queue_declare("", false, false, true, false);
        $channel->queue_bind($queue_name, 'logs');
        echo " [*] Waiting for logs. To exit press CTRL+C\n";
        $callback = function ($msg) {
            echo ' 我是订阅者开始进行消费[x] ', $msg->body, "\n";
        };
        $channel->basic_consume($queue_name, '', false, true, false, false, $callback);
        while ($channel->is_open()) {
            $channel->wait();
        }
        $channel->close();
        $connection->close();
    }
}
复制代码


三、运行截图


执行生产消息 php artisan rabbitmq_producer

执行消费消息 hp artisan rabbitmq_consumer


网络异常,图片无法展示
|


相关实践学习
快速体验阿里云云消息队列RocketMQ版
本实验将带您快速体验使用云消息队列RocketMQ版Serverless系列实例进行获取接入点、创建Topic、创建订阅组、收发消息、查看消息轨迹和仪表盘。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
相关文章
|
中间件 PHP 调度
深入浅出PHP框架之Laravel的优雅
【10月更文挑战第3天】在PHP的世界里,Laravel以其优雅和简洁闻名。本文将带你走进Laravel的世界,探索它的魔法。我们将通过代码示例,一步步揭示Laravel的魅力。准备好,让我们一起开始这场奇妙的旅程吧!
|
7月前
|
JSON 自然语言处理 前端开发
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
370 72
【01】对APP进行语言包功能开发-APP自动识别地区ip后分配对应的语言功能复杂吗?-成熟app项目语言包功能定制开发-前端以uniapp-基于vue.js后端以laravel基于php为例项目实战-优雅草卓伊凡
|
11月前
|
缓存 安全 PHP
深入浅出PHP框架之Laravel的优雅与实用
【10月更文挑战第22天】在PHP的世界里,Laravel如同一股清流,以其优雅的设计和实用的功能赢得了广大开发者的喜爱。本文将带你走进Laravel的世界,探索其背后的设计哲学,以及如何利用Laravel构建高效、可维护的Web应用。从路由到模型,从控制器到视图,我们将一步步揭开Laravel的神秘面纱。
193 3
|
存储 前端开发 PHP
深入浅出PHP框架之Laravel的优雅
【9月更文挑战第31天】在编程世界里,PHP语言如同一位多才多艺的老匠人,而Laravel框架则是其手中的精工细作。本文将带你领略Laravel的魅力所在,从其优雅的设计哲学到实用的功能特性,再到如何通过实际代码示例掌握它的核心操作。让我们一起探索Laravel的世界,发现编程之美。
158 6
|
11月前
|
前端开发 中间件 PHP
PHP框架深度解析:Laravel的魔力与实战应用####
【10月更文挑战第31天】 本文作为一篇技术深度好文,旨在揭开PHP领域璀璨明星——Laravel框架的神秘面纱。不同于常规摘要的概括性介绍,本文将直接以一段引人入胜的技术剖析开场,随后通过具体代码示例和实战案例,逐步引导读者领略Laravel在简化开发流程、提升代码质量及促进团队协作方面的卓越能力。无论你是PHP初学者渴望深入了解现代开发范式,还是经验丰富的开发者寻求优化项目架构的灵感,本文都将为你提供宝贵的见解与实践指导。 ####
|
安全 前端开发 PHP
构建与验证表单:传统PHP与Laravel框架的比较分析——探索Web开发中表单处理的优化策略和最佳实践
【8月更文挑战第31天】在 Web 开发中,表单构建与数据验证至关重要。传统 PHP 方法需手动处理 HTML 表单和数据验证,而 Laravel 框架则提供了一种更现代、高效的解决方案。本文通过对比传统 PHP 和 Laravel 的方法,探讨表单构建与验证的最佳实践。Laravel 通过简洁的语法糖、内置的数据过滤和验证机制,显著提升了代码的安全性和可维护性,适用于大型项目或需要快速开发的场景。然而,在追求灵活性的小型项目中,直接使用 PHP 仍是不错的选择。了解两者的优劣,有助于开发者根据项目需求做出最佳决策。
137 0
|
缓存 安全 PHP
深入浅出PHP框架:Laravel的优雅之旅
【8月更文挑战第15天】 探索PHP世界里的瑰宝,Laravel框架以其优雅、简洁著称。本文将带你领略Laravel的核心魅力,从安装到构建应用,再到高级特性的应用,让你轻松驾驭这个强大的工具。无论你是PHP新手还是资深开发者,这篇文章都将成为你理解并使用Laravel的指南针。
108 2
|
缓存 前端开发 API
PHP现代化之路:从传统到Laravel的演进
【8月更文挑战第4天】 在数字化浪潮不断推进的今天,PHP作为一门历史悠久的编程语言,面临着前所未有的挑战与机遇。本文将探讨PHP如何通过现代化改造,特别是Laravel框架的应用,实现从传统Web开发向现代应用架构的转变,并分析这一转变对开发者和项目带来的影响。
102 5
|
前端开发 中间件 PHP
|
缓存 中间件 PHP
Laravel 框架:优雅 PHP Web 开发的典范
【8月更文挑战第31天】
473 0