RabbitMQ之三 Publish/Subscribe
来源:互联网 发布:ifashion淘宝什么意思 编辑:程序博客网 时间:2024/05/17 12:55
在上篇文章Work Quene中我们创建了一个Work Queue,在Work Queue中的每个task会准确的分发给worker,这边文章中,我们需要将一个消息分发给多个consumers,这个模式称为发布订阅 "publish/subscribe"
为了举例说明发布订阅模式,我们构建一个简单的日志系统,包含两部分,一部分用于发布日志,另一部分用于接收并打印日志。
在我们的日志系统中,发布日志意味着将日志消息"广播"给所有的订阅者。
交换机Exchanges
首先介绍下RabbitMQ的消息模型,RabbitMQ中的Producer不会直接向queue发送消息,实际上,很多Producer不清楚消息将被分发到哪个queue,相反,Producer只能把消息发送到交换机(exchange),交换机连接着Producer和queue,一方面交换机从Producer中接收数据,另一方面交换机往queue中放数据,所以交换机必须清楚怎么处理接收到的消息,是应该添加到一个queue,还是应该添加到多个queues,或者直接丢弃,这规则取决于exchange type 交换机的模型如下
exchange type有这几种:direct,topic,headers和fanout,首先来看下fanout这种类型
fanout exchange很简单,它将从producer接收到的数据直接广播给所有它知道的queue
消息模型如下:
我们的日志系统代码如下:
客户端:EmitLog.java
package org.rabbitmq;import com.rabbitmq.client.BuiltinExchangeType;import com.rabbitmq.client.Channel;import com.rabbitmq.client.Connection;import com.rabbitmq.client.ConnectionFactory;public class EmitLog {private static final String EXCHANGE_NAME = "logs"; public static void main(String[] argv) throws Exception { ConnectionFactory factory = new ConnectionFactory(); factory.setHost("localhost"); factory.setPort(5673); Connection connection = factory.newConnection(); Channel channel = connection.createChannel(); channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.FANOUT); String message = getMessage( new String[]{"hello","how","are","you"}); channel.basicPublish(EXCHANGE_NAME, "", null, message.getBytes("UTF-8")); System.out.println(" [x] Sent '" + message + "'"); channel.close(); connection.close(); } private static String getMessage(String[] strings){ if (strings.length < 1) return "info: Hello World!"; return joinStrings(strings, " "); } private static String joinStrings(String[] strings, String delimiter) { int length = strings.length; if (length == 0) return ""; StringBuilder words = new StringBuilder(strings[0]); for (int i = 1; i < length; i++) { words.append(delimiter).append(strings[i]); } return words.toString(); }}服务端ReceiveLogs.java
package org.rabbitmq;import java.io.IOException;import com.rabbitmq.client.AMQP;import com.rabbitmq.client.Channel;import com.rabbitmq.client.Connection;import com.rabbitmq.client.ConnectionFactory;import com.rabbitmq.client.Consumer;import com.rabbitmq.client.DefaultConsumer;import com.rabbitmq.client.Envelope;public class ReceiveLogs {private static final String EXCHANGE_NAME = "logs"; public static void main(String[] argv) throws Exception { ConnectionFactory factory = new ConnectionFactory(); factory.setHost("localhost"); factory.setPort(5673); Connection connection = factory.newConnection(); Channel channel = connection.createChannel(); channel.exchangeDeclare(EXCHANGE_NAME, "fanout"); String queueName = channel.queueDeclare().getQueue(); channel.queueBind(queueName, EXCHANGE_NAME, ""); System.out.println("Thread:"+ Thread.currentThread().hashCode()+"[*] Waiting for messages. To exit press CTRL+C"); Consumer consumer = new DefaultConsumer(channel) { @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { String message = new String(body, "UTF-8"); System.out.println(" [x] Received '" + message + "'"); } }; channel.basicConsume(queueName, true, consumer); }}运行两次EmitLog,然后再运行ReceiveLogs,结果如下
结果显示从producer发送的消息,被两个consumer都接收到了。
参考:http://www.rabbitmq.com/tutorials/tutorial-three-java.html
- RabbitMQ之三 Publish/Subscribe
- RabbitMq之Publish/Subscribe
- RabbitMQ之Publish/Subscribe
- rabbitmq 教程 三 Publish/Subscribe
- RabbitMQ案例之Publish/Subscribe
- RabbitMQ学习(三).NET Client之Publish/Subscribe
- RabbitMQ系列教程之三:发布\/订阅(Publish\/Subscribe)
- Rabbitmq教程翻译(三)Publish/Subscribe
- rabbitmq(三)Publish/Subscribe(发布/订阅)
- RabbitMQ 学习笔记(三):Publish/Subscribe
- RabbitMQ(三)——Publish/Subscribe
- python系列之 RabbitMQ -- Publish/Subscribe
- RabbitMQ Publish/Subscribe
- RabbitMQ学习小结(三)—— Publish Subscribe[Python]
- rabbitmq官方教程之发布与订阅(Publish/Subscribe)
- RabbitMQ 入门四(Publish/Subscribe)
- rabbitmq学习3:Publish/Subscribe
- RabbitMQ Publish/Subscribe 发布/订阅
- disruptor
- Pandas统计特征函数
- 移动端-click、touch、tap、swipe事件
- 是离开,还是走下去!
- 获取16进制的byte[]数组的和与和的后两位校验值
- RabbitMQ之三 Publish/Subscribe
- 欢迎使用CSDN-markdown编辑器
- npm报错:error code EINTEGRITY
- CORS(跨域资源共享)理论篇
- 定时shell 导出多个mysql数据库
- 人脸识别opencv2.4.9
- C语言的不完整类型和前置声明
- 图片png,jpg转webp格式
- ELK 日志分析系统