原文:RabbitMQ入门教程(五):扇形交换机发布/订阅(Publish/Subscribe)

版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。

分享一个朋友的人工智能教程。比较通俗易懂,风趣幽默,感兴趣的朋友可以去看看。

简介

本节主要演示交换机的广播类型fanout,广播类型不需要routingKey,交换机会将所有的消息都发送到每个绑定的队列中去。

在发布消息时可以只先指定交换机的名称,交换机的声明的代码可以放到消费者端进行声明,队列的声明也放在消费者端来声明。

发布订阅类似观察者模式设计模式,一般适用于当接收到某条消息时同时做多种类似的任务的处理,如一个发短信,另一个一个发邮件;一个插入数据库,另一个保存在文件等类似操作,扇形交换机将消息传送给不同的队列,不同的队列对同一种消息采取不同的行为。

扇形交换机是最基本的交换机类型,它所能做的事情非常简单———广播消息。扇形交换机会把能接收到的消息全部发送给绑定在自己身上的队列。因为广播不需要“思考”,所以扇形交换机处理消息的速度也是所有的交换机类型里面最快的。

生产者

  1. public class Producer {
  2. @Test
  3. public void testBasicPublish() throws IOException, TimeoutException {
  4. ConnectionFactory factory = new ConnectionFactory();
  5. factory.setHost("127.0.0.1");
  6. factory.setPort(AMQP.PROTOCOL.PORT);
  7. factory.setUsername("mengday");
  8. factory.setPassword("mengday");
  9. Connection connection = factory.newConnection();
  10. Channel channel = connection.createChannel();
  11. String EXCHANGE_NAME = "exchange.fanout";
  12. // 生产者不需要队列声明,也不需要声明交换机,只需要指定交换机的名称即可,队列和交换机的声明可以在消费者中声明
  13. // 循环发布多条消息, 注意广播模式不需要routingKey, 可以写成"", 也可以随意写个名字,在消费者也随便写一个,生产者和消费者的routingKey的不一样看看可以不
  14. for (int i = 0; i < 10; i++){
  15. String message = "Hello RabbitMQ " + i;
  16. // 广播类型不需要routingKey,但是不能写成null,可以写成空字符串""
  17. channel.basicPublish(EXCHANGE_NAME, "", null, message.getBytes("UTF-8"));
  18. }
  19. // 关闭资源
  20. channel.close();
  21. connection.close();
  22. }
  23. }
  24.  
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

消费者1

  1. public class Consumer1 {
  2. @Test
  3. public void testBasicConsumer1() throws Exception{
  4. ConnectionFactory factory = new ConnectionFactory();
  5. factory.setHost("127.0.0.1");
  6. factory.setPort(AMQP.PROTOCOL.PORT);
  7. factory.setUsername("mengday");
  8. factory.setPassword("mengday");
  9. Connection connection = factory.newConnection();
  10. final Channel channel = connection.createChannel();
  11. channel.basicQos(1);
  12. String QUEUE_NAME = "queue.fanout.q1";
  13. String EXCHANGE_NAME = "exchange.fanout";
  14. channel.queueDeclare(QUEUE_NAME, false, false, false, null);
  15. // 声明交换机:指定交换机的名称和类型(广播:fanout)
  16. channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.FANOUT);
  17. // 在消费者端队列绑定
  18. channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "");
  19. System.out.println("Consumer Wating Receive Message");
  20. Consumer consumer = new DefaultConsumer(channel){
  21. @Override
  22. public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
  23. String message = new String(body, "UTF-8");
  24. System.out.println(" [C] Received '" + message + "', 处理业务中...");
  25. }
  26. };
  27. channel.basicConsume(QUEUE_NAME, true, consumer);
  28. Thread.sleep(1000000);
  29. }
  30. }
  31.  
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

消费者2

消费者2和消费者1仅仅是队列名称不一样而已

  1. public class Consumer2 {
  2. @Test
  3. public void testBasicConsumer2() throws Exception{
  4. ConnectionFactory factory = new ConnectionFactory();
  5. factory.setHost("127.0.0.1");
  6. factory.setPort(AMQP.PROTOCOL.PORT);
  7. factory.setUsername("mengday");
  8. factory.setPassword("mengday");
  9. Connection connection = factory.newConnection();
  10. final Channel channel = connection.createChannel();
  11. channel.basicQos(1);
  12. String QUEUE_NAME = "queue.fanout.q2";
  13. String EXCHANGE_NAME = "exchange.fanout";
  14. channel.queueDeclare(QUEUE_NAME, false, false, false, null);
  15. // 在消费者端队列绑定
  16. // 声明交换机:指定交换机的名称和类型(广播:fanout)
  17. channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.FANOUT);
  18. channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "");
  19. System.out.println("Consumer Wating Receive Message");
  20. Consumer consumer = new DefaultConsumer(channel){
  21. @Override
  22. public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
  23. String message = new String(body, "UTF-8");
  24. System.out.println(" [C] Received '" + message + "', 处理业务中...");
  25. }
  26. };
  27. channel.basicConsume(QUEUE_NAME, true, consumer);
  28. Thread.sleep(1000000);
  29. }
  30. }
  31.  
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

运行效果

注意:先启动消费者,再启动生产者。可以看到两个消费者都收到同样的消息


分享一个朋友的人工智能教程。比较通俗易懂,风趣幽默,感兴趣的朋友可以去看看。

我的微信公众号:

RabbitMQ入门教程(五):扇形交换机发布/订阅(Publish/Subscribe)的更多相关文章

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

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

  2. RabbitMQ学习总结 第四篇:发布/订阅 Publish/Subscribe

    目录 RabbitMQ学习总结 第一篇:理论篇 RabbitMQ学习总结 第二篇:快速入门HelloWorld RabbitMQ学习总结 第三篇:工作队列Work Queue RabbitMQ学习总结 ...

  3. ActiveMQ 快速入门教程系列 第二章 发布-订阅者模式实现

    第二章我们会介绍怎样实现一个发布者对多个订阅者的消息传递 Topic和queue的最大区别在于topic是以广播的形式,通知所有在线监听的客户端有新的消息,没有监听的客户端将收不到消息:而queue则 ...

  4. RabbitMQ入门教程(九):首部交换机Headers

    原文:RabbitMQ入门教程(九):首部交换机Headers 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog ...

  5. RabbitMQ入门教程(十五):普通集群和镜像集群

    原文:RabbitMQ入门教程(十五):普通集群和镜像集群 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.c ...

  6. RabbitMQ入门教程(七):主题交换机Topics

    原文:RabbitMQ入门教程(七):主题交换机Topics 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog. ...

  7. RabbitMQ入门教程(四):工作队列(Work Queues)

    原文:RabbitMQ入门教程(四):工作队列(Work Queues) 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https:/ ...

  8. RabbitMQ入门教程(三):Hello World

    原文:RabbitMQ入门教程(三):Hello World 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog. ...

  9. RabbitMQ入门教程(二):简介和基本概念

    原文:RabbitMQ入门教程(二):简介和基本概念 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn ...

随机推荐

  1. Mac开发如何处理键盘事件

    Mac上输入与手机输入的不同是,Mac需要处理更多的键盘交互,因为Mac上的键盘输入会有多种快捷键组合. 代理方法处理 NSTextField #pragma mark - NSTextFieldDe ...

  2. echarts_02

    1. 如果数据加载时间较长,一个空的坐标轴放在画布上也会让用户觉得是不是产生 bug 了,因此需要一个 loading 的动画来提示用户数据正在加载. ECharts 默认有提供了一个简单的加载动画. ...

  3. vue-解决弹出蒙层滑动穿透问题

    最近开发过程中遇到一些小问题(似乎问题总是那么多),但一直没什么时间去优化与解决.程序员不能被业务绑架,有时间还是花点在代码上

  4. 读取PC版微信数据库(电脑版微信数据库)内容

    原始网址   https://www.cnblogs.com/Charltsing/p/WeChatPCdb.html 1.PC版微信的密钥是32位byte,不同于安卓版(7位字符串) 2.通过OD或 ...

  5. linux新建用户tab无法补全命令

    查看passwd cat /ect/passwd 发现root用户的shell是/bin/bash 普通用户的shell是/bin/sh 修改普通用户的为/bin/bash即可

  6. 浏览器端-W3School-JavaScript-HTML DOM:HTML DOM Document 对象

    ylbtech-浏览器端-W3School-JavaScript-HTML DOM:HTML DOM Document 对象 1.返回顶部 1. HTML DOM Document 对象 Docume ...

  7. 代码实现:编写一个函数,输入n为偶数时,调用函数求1/2+1/4+...+1/n,当输入n为奇数时,调用函数1/1+1/3+...+1/n

    import java.util.Scanner; //编写一个函数,输入n为偶数时,调用函数求1/2+1/4+...+1/n,当输入n为奇数时,调用函数1/1+1/3+...+1/n public ...

  8. Jmeter(五)检查点

    录制的脚本回放成功了, 但是运行有可能出现失败的情况, 所以有必要让JMeter来帮我们验证测试结果的正确性. 在Jmeter中是用断言组件来实现此功能的. 首先, 在需要添加断言的请求后面, 添加响 ...

  9. 十五:jinja2过滤器之实现自定义过滤器

    过滤器的本质就是函数,如果在模板中调用这个过滤器,那么就会将这个变量的值作为第一个参数传给过滤器函数,然后将函数的返回值作为滤器的返回值 1.在python文件中写好过滤的函数和逻辑2.将将函数注册到 ...

  10. PS 之图片中抠出大树

    工具:Photoshop CC2017 原图:(目的是将大树从图片中抠出) 操作: 1.打开要抠图的图片,然后执行:[图层]---->[新建调整图层]---->[反相]---->[在 ...