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. CentOS7.2安装nginx失败

    错误提示: Loaded plugins: fastestmirror Loading mirror speeds from cached hostfile * base: mirrors.aliyu ...

  2. SCU - 4110 - PE class

    先上题目: 4110: PE class Submit your solution     Discuss this problem     Best solutions   Description ...

  3. 0622 CentOS 6.4下编译安装MySQL 5.6.14

    转自http://www.cnblogs.com/xiongpq/p/3384681.html 概述: CentOS 6.4下通过yum安装的MySQL是5.1版的,比较老,所以就想通过源代码安装高版 ...

  4. Linux 命令未自动提示补全

    解决方法: yum install -y bash-completion 退出当前界面,重新进入即可.

  5. Extensions for Spatial Data

    http://dev.mysql.com/worklog/task/?spm=5176.100239.blogcont4270.8.j3asa7&id=6609 前文: 这两天因为项目原因看了 ...

  6. caffe Solve函数

    下面来看Solver<Dtype>::Solve(const char* resume_file) solver.cpp template <typename Dtype> v ...

  7. [ACM] hdu 1035 Robot Motion (模拟或DFS)

    Robot Motion Problem Description A robot has been programmed to follow the instructions in its path. ...

  8. 【solr基础教程之中的一个】Solr相关知识点串讲

           Solr是Apache Lucene的一个子项目.Lucene为全文搜索功能提供了完备的API.但它仅仅作为一个API库存在.而不能直接用于搜索. 因此,Solr基于Lucene构建了一 ...

  9. #leetcode#Anagrames

    Given an array of strings, return all groups of strings that are anagrams. Note: All inputs will be ...

  10. 消息推送之百度云推送Android集成与用法

    这两天因为项目须要.研究了一下百度云推送,本来这事没什么多大工作量的,但注冊百度开发人员账户创建应用令我蛋疼菊紧了好一阵,这些东西做了对技术没啥提升,不做又不行,必经之路. 好在我耗费了N多个毫毫秒秒 ...