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

  1. package cn.slimsmart.rabbitmq.demo.fanout;
  2. import java.util.Date;
  3. import com.rabbitmq.client.AMQP;
  4. import com.rabbitmq.client.Channel;
  5. import com.rabbitmq.client.Connection;
  6. import com.rabbitmq.client.ConnectionFactory;
  7. public class SendLog {
  8. // 转发器
  9. private final static String EXCHANGE_NAME = "ex_log";
  10. @SuppressWarnings("deprecation")
  11. public static void main(String[] args) throws Exception {
  12. // 创建连接和频道
  13. ConnectionFactory factory = new ConnectionFactory();
  14. factory.setHost("192.168.101.174");
  15. // 指定用户 密码
  16. factory.setUsername("admin");
  17. factory.setPassword("admin");
  18. // 指定端口
  19. factory.setPort(AMQP.PROTOCOL.PORT);
  20. Connection connection = factory.newConnection();
  21. Channel channel = connection.createChannel();
  22. /**
  23. * 声明转发器和类型 可用的转发器类型Direct Topic Headers Fanout 参考:http://melin.iteye.com/blog/691265
  24. * Direct Exchange – 处理路由键。需要将一个队列绑定到交换机上,要求该消息与一个特定的路由键完全匹配。
  25. * Fanout Exchange – 不处理路由键。你只需要简单的将队列绑定到交换机上。一个发送到交换机的消息都会被转发到与该交换机绑定的所有队列上。
  26. * 很像子网广播,每台子网内的主机都获得了一份复制的消息。Fanout交换机转发消息是最快的。
  27. * Topic Exchange – 将路由键和某模式进行匹配。此时队列需要绑定要一个模式上。符号“#”匹配一个或多个词,符号“*”匹配不多不少一个词。
  28. * 因此“audit.#”能够匹配到“audit.irs.corporate”,但是“audit.*” 只会匹配到“audit.irs”。
  29. */
  30. channel.exchangeDeclare(EXCHANGE_NAME, "fanout");
  31. String message = new Date().toLocaleString() + " : log something";
  32. // 指定消息发送到的转发器
  33. channel.basicPublish(EXCHANGE_NAME, "", null, message.getBytes());
  34. System.out.println(" [x] Sent '" + message + "'");
  35. channel.close();
  36. connection.close();
  37. }
  38. }

2.接受写文件类代码ReceiveLogsToFile.java

创建一个队列,然后将队列与转发器绑定,然后将消费者与该队列绑定,然后写入日志文件。

  1. package cn.slimsmart.rabbitmq.demo.fanout;
  2. import java.io.File;
  3. import java.io.FileNotFoundException;
  4. import java.io.FileOutputStream;
  5. import java.io.IOException;
  6. import java.text.SimpleDateFormat;
  7. import java.util.Date;
  8. import com.rabbitmq.client.AMQP;
  9. import com.rabbitmq.client.Channel;
  10. import com.rabbitmq.client.Connection;
  11. import com.rabbitmq.client.ConnectionFactory;
  12. import com.rabbitmq.client.QueueingConsumer;
  13. public class ReceiveLogsToFile {
  14. private final static String EXCHANGE_NAME = "ex_log";
  15. public static void main(String[] args) throws Exception {
  16. // 创建连接和频道
  17. ConnectionFactory factory = new ConnectionFactory();
  18. factory.setHost("192.168.101.174");
  19. // 指定用户 密码
  20. factory.setUsername("admin");
  21. factory.setPassword("admin");
  22. // 指定端口
  23. factory.setPort(AMQP.PROTOCOL.PORT);
  24. Connection connection = factory.newConnection();
  25. Channel channel = connection.createChannel();
  26. /**
  27. * 声明转发器和类型 可用的转发器类型Direct Topic Headers Fanout
  28. * Direct Exchange – 处理路由键。需要将一个队列绑定到交换机上,要求该消息与一个特定的路由键完全匹配。
  29. * Fanout Exchange – 不处理路由键。你只需要简单的将队列绑定到交换机上。一个发送到交换机的消息都会被转发到与该交换机绑定的所有队列上。
  30. * 很像子网广播,每台子网内的主机都获得了一份复制的消息。Fanout交换机转发消息是最快的。
  31. * Topic Exchange – 将路由键和某模式进行匹配。此时队列需要绑定要一个模式上。符号“#”匹配一个或多个词,符号“*”匹配不多不少一个词。
  32. * 因此“audit.#”能够匹配到“audit.irs.corporate”,但是“audit.*” 只会匹配到“audit.irs”。
  33. */
  34. channel.exchangeDeclare(EXCHANGE_NAME, "fanout");
  35. //创建一个非持久的、唯一的且自动删除的队列且队列名称由服务器随机产生一般情况这个名称与amq.gen-JzTY20BRgKO-HjmUJj0wLg 类似。
  36. String queueName = channel.queueDeclare().getQueue();
  37. // 为转发器指定队列,设置binding
  38. channel.queueBind(queueName, EXCHANGE_NAME, "");
  39. System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
  40. QueueingConsumer consumer = new QueueingConsumer(channel);
  41. // 指定接收者,第二个参数为自动应答,无需手动应答
  42. channel.basicConsume(queueName, true, consumer);
  43. while (true) {
  44. QueueingConsumer.Delivery delivery = consumer.nextDelivery();
  45. String message = new String(delivery.getBody());
  46. print2File(message);
  47. }
  48. }
  49. private static void print2File(String msg) {
  50. try {
  51. String dir = ReceiveLogsToFile.class.getClassLoader().getResource("").getPath();
  52. String logFileName = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
  53. File file = new File(dir, logFileName + ".txt");
  54. FileOutputStream fos = new FileOutputStream(file, true);
  55. fos.write((msg + "\r\n").getBytes());
  56. fos.flush();
  57. fos.close();
  58. } catch (FileNotFoundException e) {
  59. e.printStackTrace();
  60. } catch (IOException e) {
  61. e.printStackTrace();
  62. }
  63. }
  64. }

3.接受写控制台代码ReceiveLogsToConsole.java

创建一个队列,然后将队列与转发器绑定,然后将消费者与该队列绑定,然后打印到控制台。

  1. package cn.slimsmart.rabbitmq.demo.fanout;
  2. import com.rabbitmq.client.AMQP;
  3. import com.rabbitmq.client.Channel;
  4. import com.rabbitmq.client.Connection;
  5. import com.rabbitmq.client.ConnectionFactory;
  6. import com.rabbitmq.client.QueueingConsumer;
  7. public class ReceiveLogsToConsole {
  8. private final static String EXCHANGE_NAME = "ex_log";
  9. public static void main(String[] args) throws Exception {
  10. // 创建连接和频道
  11. ConnectionFactory factory = new ConnectionFactory();
  12. factory.setHost("192.168.101.174");
  13. // 指定用户 密码
  14. factory.setUsername("admin");
  15. factory.setPassword("admin");
  16. // 指定端口
  17. factory.setPort(AMQP.PROTOCOL.PORT);
  18. Connection connection = factory.newConnection();
  19. Channel channel = connection.createChannel();
  20. channel.exchangeDeclare(EXCHANGE_NAME, "fanout");
  21. // 创建一个非持久的、唯一的且自动删除的队列且队列名称由服务器随机产生一般情况这个名称与amq.gen-JzTY20BRgKO-HjmUJj0wLg 类似。
  22. String queueName = channel.queueDeclare().getQueue();
  23. // 为转发器指定队列,设置binding
  24. channel.queueBind(queueName, EXCHANGE_NAME, "");
  25. System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
  26. QueueingConsumer consumer = new QueueingConsumer(channel);
  27. // 指定接收者,第二个参数为自动应答,无需手动应答
  28. channel.basicConsume(queueName, true, consumer);
  29. while (true)
  30. {
  31. QueueingConsumer.Delivery delivery = consumer.nextDelivery();
  32. String message = new String(delivery.getBody());
  33. System.out.println(" [x] Received '" + message + "'");
  34. }
  35. }
  36. }

先启动2个消费者,再运行生产者观察消费者运行情况,可见2个消费者都受到相同的消息。生产者将消息发送至转发器,转发器决定将消息发送至哪些队列,消费者绑定队列获取消息。

(转) RabbitMQ学习之发布/订阅(java)的更多相关文章

  1. 【Redis数据库】命令学习笔记——发布订阅、事务、脚本、连接等命令汇总

    本篇基于redis 4.0.11版本,学习发布订阅.事务.脚本.连接的相关命令. Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息. 序号 ...

  2. RabbitMQ入门(3)——发布/订阅(Publish/Subscribe)

    在上一篇RabbitMQ入门(2)--工作队列中,有一个默认的前提:每个任务都只发送到一个工作人员.这一篇将介绍发送一个消息到多个消费者.这种模式称为发布/订阅(Publish/Subscribe). ...

  3. 4.RabbitMQ系列之发布/订阅模式

    我们把一个消息转发给多个消费者,这种模式称之为发布-订阅模式 1.交换器(Exchange) RabbitMq消息模式的核心思想是:一个生产者并不会直接往一个队列中发送消息,事实上,生产者根本不知道它 ...

  4. rabbitmq消息队列——"发布订阅"

    三."发布订阅" 上一节的练习中我们创建了一个工作队列.队列中的每条消息都会被发送至一个工作进程.这节,我们将做些完全不同的事情--我们将发送单个消息发送至多个消费者.这种模式就是 ...

  5. RabbitMQ入门教程——发布/订阅

    什么是发布订阅 发布订阅是一种设计模式定义了一对多的依赖关系,让多个订阅者对象同时监听某一个主题对象.这个主题对象在自身状态变化时,会通知所有的订阅者对象,使他们能够自动更新自己的状态. 为了描述这种 ...

  6. RabbitMQ入门:发布/订阅(Publish/Subscribe)

    在前面的两篇博客中 RabbitMQ入门:Hello RabbitMQ 代码实例 RabbitMQ入门:工作队列(Work Queue) 遇到的实例都是一个消息只发送给一个消费者(工作者),他们的消息 ...

  7. redis发布订阅Java代码实现

    Redis除了可以用作缓存数据外,另一个重要用途是它实现了发布订阅(pub/sub)消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息. 为了实现redis的发布订阅机制,首先要打开re ...

  8. (转) RabbitMQ学习之helloword(java)

    http://blog.csdn.net/zhu_tianwei/article/details/40835555 amqp-client:http://www.rabbitmq.com/java-c ...

  9. (转)RabbitMQ学习之路由(java)

    http://blog.csdn.net/zhu_tianwei/article/details/40887755 参考:http://blog.csdn.NET/lmj623565791/artic ...

随机推荐

  1. sass使用中出现的问题

    问题一:ruby按照官方文档安装后更换gem源时,报错Error fetching https://gems.ruby-china.org/: bad response Not Found 404 ( ...

  2. PHP过滤html注释

    过滤html注释: 所谓过滤,不过是字符串的匹配与替换,这里我们用到的正则匹配替换函数preg_replace(reg,replace,string);,PHPer都清楚,这个函数的关键在于reg的精 ...

  3. BeanUtils.copyProperties()错误使用,给自己挖了坑

    场景:需要对某个集合中的所有元素拷贝到另一个集合中,想着BeanUtils.copyProperties()可以深拷贝对象,误以为也可以拷贝集合,于是乎写下了如下代码 List<CostRule ...

  4. 实用的 鼠标滑上显示提示信息的jq插件

    使用非常简单, 引用 css js文件, 将需要显示提示信息的元素 添加class="tooltip"类名, 在title属性填写提示信息就好了title="啊啊啊啊&q ...

  5. java IO(BIO)、NIO、AIO

    IO 服务端ServerSocket 客户端Socket 缺点每次客户端建立连接都会另外启一个线程处理.读取和发送数据都是阻塞式的. 如果1000个客户端建立连接将会产生1000个线程 Server端 ...

  6. 服务器监控(包括性能指标与web应用程序)

    http://blog.csdn.net/yao123long/article/details/53142029 http://blog.csdn.net/heyongluoyao8/article/ ...

  7. 洛谷 P1692 部落卫队

    P1692 部落卫队 题目描述 原始部落byteland中的居民们为了争夺有限的资源,经常发生冲突.几乎每个居民都有他的仇敌.部落酋长为了组织一支保卫部落的队伍,希望从部落的居民中选出最多的居民入伍, ...

  8. js休眠

    <!DOCTYPE html><html><meta http-equiv="Content-Type" content="text/htm ...

  9. SEO 爬虫原理介绍

    一篇关于网络爬虫程序的一些原理及体系结构纯技术文章,一些地方可能不会看的非常明确.对于SEO行业,常常和搜索引擎及其爬虫程序打交道,细致浏览下,一些不清楚而自己又非常想了解的地方,能够借助搜索来需找相 ...

  10. MVC地区多级联动扩展实现(非递归形式)

    MVC前台界面调用方式如下: @Html.AreaDropDownList(, string.Empty) 参数说明: 第一个参数控件的名称: 第二个参数选中的地区编码: 第三个参数地区层级: 第四个 ...