PHP使用RabbitMQ实例

简介: 这篇笔记记录了php连接rabbitmq实现消息的生产和消费的整个过程,包括声明持久的直连交换机,声明持久的队列,以及生产持久的消息,消费者处理消息等

相关笔记:
CentOS6.9安装RabbitMQ和源码编译安装php的RabbitMQ扩展
RabbitMQ入门基础
CentOS7源码编译安装nginx+php7.2+mysql5.7并使用systemctl管理
RabbitMQ的安装过程,工作流程,和一些基础概念已经在前面的笔记中提到了,今天在本地实现了php连接RabbitMQ,以及消息的生产和消费的过程,首先看下没有生产者和消费者的默认RabbitMQ管理界面截图:
Connections:

还没有任何连接(Connections)
Channels:

还没有任何通道(Channels)
Exchanges:

交换机只有系统默认的
Queues:

还没有任何队列
先上消费者代码consumer.php

<?php
/**
 * Created by PhpStorm.
 * User: jmsite.cn
 * Date: 2019/1/15
 * Time: 13:16
 */
//声明连接参数
$config = array(
    'host' => '192.168.75.132',
    'vhost' => '/',
    'port' => 5672,
    'login' => 'test',
    'password' => 'test'
);
//连接broker
$cnn = new AMQPConnection($config);
if (!$cnn->connect()) {
    echo "Cannot connect to the broker";
    exit();
}
//在连接内创建一个通道
$ch = new AMQPChannel($cnn);
//创建一个交换机
$ex = new AMQPExchange($ch);
//声明路由键
$routingKey = 'key_1';
//声明交换机名称
$exchangeName = 'exchange_1';
//设置交换机名称
$ex->setName($exchangeName);
//设置交换机类型
//AMQP_EX_TYPE_DIRECT:直连交换机
//AMQP_EX_TYPE_FANOUT:扇形交换机
//AMQP_EX_TYPE_HEADERS:头交换机
//AMQP_EX_TYPE_TOPIC:主题交换机
$ex->setType(AMQP_EX_TYPE_DIRECT);
//设置交换机持久
$ex->setFlags(AMQP_DURABLE);
//声明交换机
$ex->declareExchange();
//创建一个消息队列
$q = new AMQPQueue($ch);
//设置队列名称
$q->setName('queue_1');
//设置队列持久
$q->setFlags(AMQP_DURABLE);
//声明消息队列
$q->declareQueue();
//交换机和队列通过$routingKey进行绑定
$q->bind($ex->getName(), $routingKey);
//接收消息并进行处理的回调方法
function receive($envelope, $queue) {
    //休眠两秒,
    sleep(2);
    //echo消息内容
    echo $envelope->getBody()."\n";
    //显式确认,队列收到消费者显式确认后,会删除该消息
    $queue->ack($envelope->getDeliveryTag());
}
//设置消息队列消费者回调方法,并进行阻塞
$q->consume("receive");
//$q->consume("receive", AMQP_AUTOACK);//隐式确认,不推荐

以上是消费者代码,打开两个命令行/终端
输入php consumer.php,消费者开始阻塞获取消息,如下图

此时再看RabbitMQ管理界面:
Connections

出现两个连接,这两个就是消费者,因为他们在阻塞着等待消息
Channels

消费者在各自的连接里都打开了一个通道
Exchanges

其中一个消费者创建了一个持久的直连交换机
Queues

消息队列已经创建,但消息数是0,因为此时还没有生产者
生产者代码publisher.php

<?php
/**
 * Created by PhpStorm.
 * User: jmsite.cn
 * Date: 2019/1/15
 * Time: 13:15
 */

$config = array(
    'host' => '192.168.75.132',
    'vhost' => '/',
    'port' => 5672,
    'login' => 'test',
    'password' => 'test'
);
$cnn = new AMQPConnection($config);
if (!$cnn->connect()) {
    echo "Cannot connect to the broker";
    exit();
}
$ch = new AMQPChannel($cnn);
$ex = new AMQPExchange($ch);
//消息的路由键,一定要和消费者端一致
$routingKey = 'key_1';
//交换机名称,一定要和消费者端一致,
$exchangeName = 'exchange_1';
$ex->setName($exchangeName);
$ex->setType(AMQP_EX_TYPE_DIRECT);
$ex->setFlags(AMQP_DURABLE);
$ex->declareExchange();
//创建10个消息
for ($i=1;$i<=10;$i++){
    //消息内容
    $msg = array(
        'data'  => 'message_'.$i,
        'hello' => 'world',
    );
    //发送消息到交换机,并返回发送结果
    //delivery_mode:2声明消息持久,持久的队列+持久的消息在RabbitMQ重启后才不会丢失
    echo "Send Message:".$ex->publish(json_encode($msg), $routingKey, AMQP_NOPARAM, array('delivery_mode' => 2))."\n";
    //代码执行完毕后进程会自动退出
}

以上是生产者代码
在执行之前,先关掉前面的两个消费者,打开一个命令行/终端,输入php publisher.php,由于生产者不需要阻塞,执行完进程便退出,所以现在RabbitMQ管理界面中既没有Connections也没有Channels,但是Queues已经被Exchanges投递过去了10条消息,如下图:

因为我们执行生产者之前已经关掉了全部消费者,所以此时消息在队列中等待获取;
因为在发送消息时设置了delivery_mode:2来声明消息持久化,此时如果重启RabbitMQ,消息还会恢复;此时重新执行消费者,假设还是两个,打开两个命令行/终端,输入php consumer.php,我们可以看到消息被消费,如下图:

提醒:生产者在生产消息时,如果不存在指定队列,并且没有创建队列,或者队列存在但消息路由键和交换机与队列绑定的键(路由规则)不一致(直连交换机必须一致),则消息会被交换机丢弃。
原文地址:https://www.jmsite.cn/blog-512.html

相关实践学习
RocketMQ一站式入门使用
从源码编译、部署broker、部署namesrv,使用java客户端首发消息等一站式入门RocketMQ。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
相关文章
|
22天前
|
物联网
MQTT常见问题之用单片机接入阿里MQTT实例失败如何解决
MQTT(Message Queuing Telemetry Transport)是一个轻量级的、基于发布/订阅模式的消息协议,广泛用于物联网(IoT)中设备间的通信。以下是MQTT使用过程中可能遇到的一些常见问题及其答案的汇总:
|
10月前
|
消息中间件 存储 缓存
RocketMQ工作原理详解及开发实例
RocketMQ工作原理详解及开发实例
504 0
|
3月前
|
消息中间件 PHP 开发工具
阿里云OpenAPI RocketMQ 5.0的PHP收发消息文档可以在阿里云开发者门户中找到
【1月更文挑战第22天】【1月更文挑战第108篇】阿里云OpenAPI RocketMQ 5.0的PHP收发消息文档可以在阿里云开发者门户中找到
58 6
|
3月前
|
消息中间件 Java Spring
RabbitMQ各种模式的含义与Spring Boot实例详解
RabbitMQ各种模式的含义与Spring Boot实例详解
33 0
|
3月前
|
消息中间件 数据可视化 Ubuntu
php laravel5.5使用rabbitmq消息队列
php laravel5.5使用rabbitmq消息队列
27 0
|
4月前
|
网络安全 PHP
[网络安全/CTF] BUUCTF极客大挑战2019PHP解题详析(Dirsearch使用实例+php反序列化)
[网络安全/CTF] BUUCTF极客大挑战2019PHP解题详析(Dirsearch使用实例+php反序列化)
39 0
|
4月前
|
消息中间件 网络协议 Java
RabbitMQ消息队列基础详解与安装实例
RabbitMQ消息队列基础详解与安装实例
121 0
|
9月前
|
消息中间件 数据可视化 Ubuntu
php laravel5.5使用rabbitmq消息队列
php laravel5.5使用rabbitmq消息队列
47 0
|
10月前
|
消息中间件 存储 负载均衡
RabbitMQ 详解及实例(含错误信息处理)
RabbitMQ 详解及实例(含错误信息处理)
147 0
|
11月前
|
存储 网络安全 PHP
[CTF/网络安全]攻防世界unserialize3解题详析及php序列化反序列化实例讲解
序列化是指将数据结构或对象转换为可传输或可存储的格式的过程。这通常需要将数据转换为字节流或其他形式的编码格式,以便能够在不同的系统和应用程序之间进行传输或存储。
209 0