(转) RabbitMQ学习之发布/订阅(java)
http://blog.csdn.net/zhu_tianwei/article/details/40887733
参考:http://blog.csdn.NET/lmj623565791/article/details/37657225
模拟发布订阅模式,一个消息发给多个消费者。实现一个发送日志,一个接收者将接收到的数据写到硬盘上,与此同时,另一个接收者把接收到的消息展现在屏幕上。
转发器类型使用:fanout。fanout类型转发器特别简单,把所有它介绍到的消息,广播到所有它所知道的队列。
channel.exchangeDeclare("logs","fanout");
1.发送日志SendLog.Java
- package cn.slimsmart.rabbitmq.demo.fanout;
- import java.util.Date;
- import com.rabbitmq.client.AMQP;
- import com.rabbitmq.client.Channel;
- import com.rabbitmq.client.Connection;
- import com.rabbitmq.client.ConnectionFactory;
- public class SendLog {
- // 转发器
- private final static String EXCHANGE_NAME = "ex_log";
- @SuppressWarnings("deprecation")
- public static void main(String[] args) throws Exception {
- // 创建连接和频道
- ConnectionFactory factory = new ConnectionFactory();
- factory.setHost("192.168.101.174");
- // 指定用户 密码
- factory.setUsername("admin");
- factory.setPassword("admin");
- // 指定端口
- factory.setPort(AMQP.PROTOCOL.PORT);
- Connection connection = factory.newConnection();
- Channel channel = connection.createChannel();
- /**
- * 声明转发器和类型 可用的转发器类型Direct Topic Headers Fanout 参考:http://melin.iteye.com/blog/691265
- * Direct Exchange – 处理路由键。需要将一个队列绑定到交换机上,要求该消息与一个特定的路由键完全匹配。
- * Fanout Exchange – 不处理路由键。你只需要简单的将队列绑定到交换机上。一个发送到交换机的消息都会被转发到与该交换机绑定的所有队列上。
- * 很像子网广播,每台子网内的主机都获得了一份复制的消息。Fanout交换机转发消息是最快的。
- * Topic Exchange – 将路由键和某模式进行匹配。此时队列需要绑定要一个模式上。符号“#”匹配一个或多个词,符号“*”匹配不多不少一个词。
- * 因此“audit.#”能够匹配到“audit.irs.corporate”,但是“audit.*” 只会匹配到“audit.irs”。
- */
- channel.exchangeDeclare(EXCHANGE_NAME, "fanout");
- String message = new Date().toLocaleString() + " : log something";
- // 指定消息发送到的转发器
- channel.basicPublish(EXCHANGE_NAME, "", null, message.getBytes());
- System.out.println(" [x] Sent '" + message + "'");
- channel.close();
- connection.close();
- }
- }
2.接受写文件类代码ReceiveLogsToFile.java
创建一个队列,然后将队列与转发器绑定,然后将消费者与该队列绑定,然后写入日志文件。
- package cn.slimsmart.rabbitmq.demo.fanout;
- import java.io.File;
- import java.io.FileNotFoundException;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.text.SimpleDateFormat;
- import java.util.Date;
- import com.rabbitmq.client.AMQP;
- import com.rabbitmq.client.Channel;
- import com.rabbitmq.client.Connection;
- import com.rabbitmq.client.ConnectionFactory;
- import com.rabbitmq.client.QueueingConsumer;
- public class ReceiveLogsToFile {
- private final static String EXCHANGE_NAME = "ex_log";
- public static void main(String[] args) throws Exception {
- // 创建连接和频道
- ConnectionFactory factory = new ConnectionFactory();
- factory.setHost("192.168.101.174");
- // 指定用户 密码
- factory.setUsername("admin");
- factory.setPassword("admin");
- // 指定端口
- factory.setPort(AMQP.PROTOCOL.PORT);
- Connection connection = factory.newConnection();
- Channel channel = connection.createChannel();
- /**
- * 声明转发器和类型 可用的转发器类型Direct Topic Headers Fanout
- * Direct Exchange – 处理路由键。需要将一个队列绑定到交换机上,要求该消息与一个特定的路由键完全匹配。
- * Fanout Exchange – 不处理路由键。你只需要简单的将队列绑定到交换机上。一个发送到交换机的消息都会被转发到与该交换机绑定的所有队列上。
- * 很像子网广播,每台子网内的主机都获得了一份复制的消息。Fanout交换机转发消息是最快的。
- * Topic Exchange – 将路由键和某模式进行匹配。此时队列需要绑定要一个模式上。符号“#”匹配一个或多个词,符号“*”匹配不多不少一个词。
- * 因此“audit.#”能够匹配到“audit.irs.corporate”,但是“audit.*” 只会匹配到“audit.irs”。
- */
- channel.exchangeDeclare(EXCHANGE_NAME, "fanout");
- //创建一个非持久的、唯一的且自动删除的队列且队列名称由服务器随机产生一般情况这个名称与amq.gen-JzTY20BRgKO-HjmUJj0wLg 类似。
- String queueName = channel.queueDeclare().getQueue();
- // 为转发器指定队列,设置binding
- channel.queueBind(queueName, EXCHANGE_NAME, "");
- System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
- QueueingConsumer consumer = new QueueingConsumer(channel);
- // 指定接收者,第二个参数为自动应答,无需手动应答
- channel.basicConsume(queueName, true, consumer);
- while (true) {
- QueueingConsumer.Delivery delivery = consumer.nextDelivery();
- String message = new String(delivery.getBody());
- print2File(message);
- }
- }
- private static void print2File(String msg) {
- try {
- String dir = ReceiveLogsToFile.class.getClassLoader().getResource("").getPath();
- String logFileName = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
- File file = new File(dir, logFileName + ".txt");
- FileOutputStream fos = new FileOutputStream(file, true);
- fos.write((msg + "\r\n").getBytes());
- fos.flush();
- fos.close();
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
3.接受写控制台代码ReceiveLogsToConsole.java
创建一个队列,然后将队列与转发器绑定,然后将消费者与该队列绑定,然后打印到控制台。
- package cn.slimsmart.rabbitmq.demo.fanout;
- import com.rabbitmq.client.AMQP;
- import com.rabbitmq.client.Channel;
- import com.rabbitmq.client.Connection;
- import com.rabbitmq.client.ConnectionFactory;
- import com.rabbitmq.client.QueueingConsumer;
- public class ReceiveLogsToConsole {
- private final static String EXCHANGE_NAME = "ex_log";
- public static void main(String[] args) throws Exception {
- // 创建连接和频道
- ConnectionFactory factory = new ConnectionFactory();
- factory.setHost("192.168.101.174");
- // 指定用户 密码
- factory.setUsername("admin");
- factory.setPassword("admin");
- // 指定端口
- factory.setPort(AMQP.PROTOCOL.PORT);
- Connection connection = factory.newConnection();
- Channel channel = connection.createChannel();
- channel.exchangeDeclare(EXCHANGE_NAME, "fanout");
- // 创建一个非持久的、唯一的且自动删除的队列且队列名称由服务器随机产生一般情况这个名称与amq.gen-JzTY20BRgKO-HjmUJj0wLg 类似。
- String queueName = channel.queueDeclare().getQueue();
- // 为转发器指定队列,设置binding
- channel.queueBind(queueName, EXCHANGE_NAME, "");
- System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
- QueueingConsumer consumer = new QueueingConsumer(channel);
- // 指定接收者,第二个参数为自动应答,无需手动应答
- channel.basicConsume(queueName, true, consumer);
- while (true)
- {
- QueueingConsumer.Delivery delivery = consumer.nextDelivery();
- String message = new String(delivery.getBody());
- System.out.println(" [x] Received '" + message + "'");
- }
- }
- }
先启动2个消费者,再运行生产者观察消费者运行情况,可见2个消费者都受到相同的消息。生产者将消息发送至转发器,转发器决定将消息发送至哪些队列,消费者绑定队列获取消息。
(转) RabbitMQ学习之发布/订阅(java)的更多相关文章
- 【Redis数据库】命令学习笔记——发布订阅、事务、脚本、连接等命令汇总
本篇基于redis 4.0.11版本,学习发布订阅.事务.脚本.连接的相关命令. Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息. 序号 ...
- RabbitMQ入门(3)——发布/订阅(Publish/Subscribe)
在上一篇RabbitMQ入门(2)--工作队列中,有一个默认的前提:每个任务都只发送到一个工作人员.这一篇将介绍发送一个消息到多个消费者.这种模式称为发布/订阅(Publish/Subscribe). ...
- 4.RabbitMQ系列之发布/订阅模式
我们把一个消息转发给多个消费者,这种模式称之为发布-订阅模式 1.交换器(Exchange) RabbitMq消息模式的核心思想是:一个生产者并不会直接往一个队列中发送消息,事实上,生产者根本不知道它 ...
- rabbitmq消息队列——"发布订阅"
三."发布订阅" 上一节的练习中我们创建了一个工作队列.队列中的每条消息都会被发送至一个工作进程.这节,我们将做些完全不同的事情--我们将发送单个消息发送至多个消费者.这种模式就是 ...
- RabbitMQ入门教程——发布/订阅
什么是发布订阅 发布订阅是一种设计模式定义了一对多的依赖关系,让多个订阅者对象同时监听某一个主题对象.这个主题对象在自身状态变化时,会通知所有的订阅者对象,使他们能够自动更新自己的状态. 为了描述这种 ...
- RabbitMQ入门:发布/订阅(Publish/Subscribe)
在前面的两篇博客中 RabbitMQ入门:Hello RabbitMQ 代码实例 RabbitMQ入门:工作队列(Work Queue) 遇到的实例都是一个消息只发送给一个消费者(工作者),他们的消息 ...
- redis发布订阅Java代码实现
Redis除了可以用作缓存数据外,另一个重要用途是它实现了发布订阅(pub/sub)消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息. 为了实现redis的发布订阅机制,首先要打开re ...
- (转) RabbitMQ学习之helloword(java)
http://blog.csdn.net/zhu_tianwei/article/details/40835555 amqp-client:http://www.rabbitmq.com/java-c ...
- (转)RabbitMQ学习之路由(java)
http://blog.csdn.net/zhu_tianwei/article/details/40887755 参考:http://blog.csdn.NET/lmj623565791/artic ...
随机推荐
- C#第二节课
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...
- HLPP算法 一种高效的网络最大流算法
#include <algorithm> #include <cstdio> #include <cctype> #include <queue> #d ...
- 4.Spring注解+SpringMVC注解+MyBatis注解(动态sql)
1.创建如图所示项目结构 2.在项目的
- base64模块 简单了解
base64,字符串文本编码解码,方便数据进行传输 import base64 '''编码解码''' st = 'ni hao'.encode('utf8') result = base64.b64e ...
- 通用 mapper
一.为什么需要通用 mapper 插件 通用 mapper 插件可以自动的生成 sql 语句. 虽然 mybatis 有逆向工程,可以直接生成 XxxMapper.xml 文件,但是这种生成的方式存在 ...
- orcale 多表连接
多表连接:
- wcf--知识点
WCF创建自托管服务 //自托管 WCF服务 //1.创建宿主 ServiceHost host = new ServiceHost(typeof(TaoBaoWCFServiceContract.T ...
- hdu1203--D - I NEED A OFFER!(转化01背包)
D - I NEED A OFFER! Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u ...
- POJ 3281(Dining-网络流拆点)[Template:网络流dinic]
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbmlrZTBnb29k/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA ...
- 新手git: ssh: connect to host localhost port 22: Connection refused
由于gitlab上要git pull或者git clone,可是每次都出现这个问题.之前偶尔出现这个问题.可是仅仅是偶尔.这是为什么呢?然后就開始搜索网上的解决方式了. 这个问题搜索网上非常多答案.可 ...