(七)RabbitMQ消息队列-通过fanout模式将消息推送到多个Queue中
来源:互联网 发布:淘宝店铺行业排名 编辑:程序博客网 时间:2024/06/07 03:37
前面第六章我们使用的是direct直连模式来进行消息投递和分发。本章将介绍如何使用fanout模式将消息推送到多个队列。
有时我们会遇到这样的情况,多个功能模块都希望得到完整的消息数据。例如一个log的消息,一个我们希望输出在屏幕上实时监控,另外一个用户持久化日志。这时就可以使用fanout模式。fanout模式模式不像direct模式通过routingkey来进行匹配,而是会把消息发送到所以的已经绑定的队列中。
新建fanout.php用来发布消息。ca.php和cb.php用来订阅不同队列消费消息。
fanout.php
<?php/* * RabbitMQ fanout * create by superrd */$exchangeName = 'log';$message = 'log--';$connection = new AMQPConnection(array('host' => '10.99.121.137', 'port' => '5672', 'vhost' => '/', 'login' => 'superrd', 'password' => 'superrd'));$connection->connect() or die("Cannot connect to the broker!\n");try { $channel = new AMQPChannel($connection); $exchange = new AMQPExchange($channel); $exchange->setName($exchangeName); $exchange->setType(AMQP_EX_TYPE_FANOUT); $exchange->setFlags(AMQP_DURABLE); $exchange->declareExchange(); for($i=0 ; $i<100;$i++){ $exchange->publish($message.$i,""); var_dump("[x] Sent $message $i"); }} catch (AMQPConnectionException $e) { var_dump($e); exit();} $connection->disconnect();
ca.php
<?php/* * RabbitMQ fanout 模式 * create by superrd */$exchangeName = 'log';$queueName = 'queuea';$routeKey = '';$connection = new AMQPConnection(array('host' => '10.99.121.137','port' => '5672', 'vhost' => '/', 'login' => 'superrd', 'password' => 'superrd'));$connection->connect() or die("Cannot connect to the broker!\n");$channel = new AMQPChannel($connection);$exchange = new AMQPExchange($channel);$exchange->setName($exchangeName);$exchange->setType(AMQP_EX_TYPE_FANOUT);$exchange->setFlags(AMQP_DURABLE);$exchange->declareExchange();$queue = new AMQPQueue($channel);$queue->setName($queueName);$queue->setFlags(AMQP_DURABLE);$queue->declareQueue();$queue->bind($exchangeName, $routeKey);//阻塞模式接收消息echo "Message:\n";while(True){ $queue->consume('processMessage'); //$queue->consume('processMessage', AMQP_AUTOACK); //自动ACK应答}$conn->disconnect();/*** 消费回调函数* 处理消息*/function processMessage($envelope, $q) { $msg = $envelope->getBody(); sleep(1); echo $msg."\n"; //处理消息 $q->ack($envelope->getDeliveryTag()); //手动发送ACK应答}
cb.php
/* * RabbitMQ fanout 模式 * create by superrd */$exchangeName = 'log';$queueName = 'queueb';$routeKey = '';$connection = new AMQPConnection(array('host' => '10.99.121.137','port' => '5672', 'vhost' => '/', 'login' => 'superrd', 'password' => 'superrd'));$connection->connect() or die("Cannot connect to the broker!\n");$channel = new AMQPChannel($connection);$exchange = new AMQPExchange($channel);$exchange->setName($exchangeName);$exchange->setType(AMQP_EX_TYPE_FANOUT);$exchange->setFlags(AMQP_DURABLE);$exchange->declareExchange();$queue = new AMQPQueue($channel);$queue->setName($queueName);$queue->setFlags(AMQP_DURABLE);$queue->declareQueue();$queue->bind($exchangeName, $routeKey);//阻塞模式接收消息echo "Message:\n";while(True){ $queue->consume('processMessage'); //$queue->consume('processMessage', AMQP_AUTOACK); //自动ACK应答}$conn->disconnect();/*** 消费回调函数* 处理消息*/function processMessage($envelope, $q) { $msg = $envelope->getBody(); sleep(1); echo $msg."\n"; //处理消息 $q->ack($envelope->getDeliveryTag()); //手动发送ACK应答}
可以看到ca和cb收到的消息完全一致。注意以上代码fanout.php中并没有新建队列,所以先运行ca.php和cb.php的脚本,如果先运行fanout.php因为找不到绑定的队列数据就会丢失。
还有一种情况我们有可能随时增加一项处理机制,如果在声明queue时不指定名字,那么RabbitMQ会随机为我们生成一个名字,如果不指定queue为持久化队列那在消息为空并且订阅者为0时自动删除该队列。这样Queue挥之即来呼之即去。
<?php/* * RabbitMQ fanout 模式 * create by superrd */$exchangeName = 'log';$connection = new AMQPConnection(array('host' => '10.99.121.137','port' => '5672', 'vhost' => '/', 'login' => 'superrd', 'password' => 'superrd'));$connection->connect() or die("Cannot connect to the broker!\n");$channel = new AMQPChannel($connection);$exchange = new AMQPExchange($channel);$exchange->setName($exchangeName);$exchange->setType(AMQP_EX_TYPE_FANOUT);$exchange->setFlags(AMQP_DURABLE);$exchange->declareExchange();$queue = new AMQPQueue($channel);$queue->declareQueue();$queue->bind($exchangeName, $routeKey);//阻塞模式接收消息echo "Message:\n";while(True){ $queue->consume('processMessage'); //$queue->consume('processMessage', AMQP_AUTOACK); //自动ACK应答}$conn->disconnect();/*** 消费回调函数* 处理消息*/function processMessage($envelope, $q) { $msg = $envelope->getBody(); sleep(1); echo $msg."\n"; //处理消息 $q->ack($envelope->getDeliveryTag()); //手动发送ACK应答}
RabbitMQ技术交流QQ群:327034977(添加时请备注RabbitMQ)
0 0
- (七)RabbitMQ消息队列-通过fanout模式将消息推送到多个Queue中
- (九)RabbitMQ消息队列-通过Headers模式分发消息
- (八)RabbitMQ消息队列-通过Topic主题模式分发消息
- RabbitMQ(消息队列)
- RabbitMQ消息队列安装和配置以及推送消息
- php amqp 消息队列 RabbitMQ 交换器类型 广播 fanout (四)
- 通过haproxy 配置rabbitmq消息队列主从
- 消息队列-RabbitMq(PHP)
- 消息队列-RabbitMq(PHP)
- RabbitMQ(python实现)学习之二:Producer发送消息至多个消息队列queue(广播消息)
- 消息队列(Message Queue)
- 消息队列(Message Queue)
- 消息队列(Message Queue)
- 消息队列(Message Queue)
- 消息队列(Message Queue)
- 消息队列(message queue)
- RabbitMQ消息队列(1)走进RabbitMQ
- RabbitMQ五种消息队列学习(三)--Work模式
- Scala匿名类的函数是private还是public?
- GLFW
- SQL SERVER【非域环境】同步复制(合并)之搭建篇
- Gradle for Android 第五篇( 多模块构建 )
- Xmlspy中如何创建元素组和属性组
- (七)RabbitMQ消息队列-通过fanout模式将消息推送到多个Queue中
- Android Token的作用
- VI 常用指令
- 题目1462:两船载物问题
- mac版 Intellij IDEA 弹窗报 this license XXXXXXXX has been cancelled
- 对于内存泄露的查找
- QPainterPath 用法
- [LeetCode]401. Binary Watch
- Error