精选文章 RabbitMQ之Exchange、Queue参数详解

RabbitMQ之Exchange、Queue参数详解

作者:Data & safety 时间: 2020-08-05 04:36:51
Data & safety 2020-08-05 04:36:51

1.先来介绍RabbitMQ中的成员

  • Producer(生产者): 将消息发送到Exchange
  • Exchange(交换器):将从生产者接收到的消息路由到Queue
  • Queue(队列):存放供消费者消费的消息
  • BindingKey(绑定键):建立Exchange与Queue之间的关系(个人看作是一种规则,也就是Exchange将什么样的消息路由到Queue)
  • RoutingKey(路由键):Producer发送消息与路由键给Exchange,Exchange将判断RoutingKey是否符合BindingKey,如何则将该消息路由到绑定的Queue
  • Consumer(消费者):从Queue中获取消息

下面是各个成员的作用图解

RabbitMQ之Exchange、Queue参数详解1
引入依赖


    com.rabbitmq
    amqp-client
    5.6.0

2.先来介绍Exchange

这里将着重于介绍Exchange和Queue的各个参数解释

先来看看Exchange中都有哪些属性

  • exchange:名称
  • type:类型
  • durable:是否持久化,RabbitMQ关闭后,没有持久化的Exchange将被清除
  • autoDelete:是否自动删除,如果没有与之绑定的Queue,直接删除
  • internal:是否内置的,如果为true,只能通过Exchange到Exchange
  • arguments:结构化参数

type会在后面一节说到,这里不会讲

Exchange.DeclareOk exchangeDeclare(String exchange,
           String type,
           boolean durable,
           boolean autoDelete,
           boolean internal,
           Map arguments) throws IOException;

下面这个类用于创建一个与RabbitMQ的Connection(连接),该Connection用于创建Channel(信道),Channel是消息读写的通道,也就是我们的操作都会在Channel的基础之上进行

package com.dfyang.rabbitmq;

import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

public class RabbitmqConnectionFactory {
    private static ConnectionFactory factory = new ConnectionFactory();

    private static String HOST = "192.168.195.123";
    private static int PORT = 5672;
    private static String USERNAME = "root";
    private static String PASSWORD = "151310";

    static {
        factory.setHost(HOST);
        factory.setPort(PORT);
        factory.setUsername(USERNAME);
        factory.setPassword(PASSWORD);
    }

    public static Connection newConnection() {
        try {
            return factory.newConnection();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

2.1先使用最简单的参数构建Exchange
exchangeDeclare(String exchange, String type)

package com.dfyang.rabbitmq.eq0;

import com.dfyang.rabbitmq.RabbitmqConnectionFactory;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;

public class Exchange {

    private static String EXCHANGE_NAME = "exchange.0";

    public static void main(String[] args) throws Exception {
    	//创建一个Connection连接
        Connection connection = RabbitmqConnectionFactory.newConnection();
        //开启Channel
        Channel channel = connection.createChannel();
        //创建一个Exchange,设置名称为exchange.0和类型为direct
        channel.exchangeDeclare(EXCHANGE_NAME, "direct");
        //关闭资源
        channel.close();
        connection.close();
    }
}

进入RabbitMQ可视化界面可以看到,RabbitMQ已经为我们创建了exchange.0,类型为direct
不懂如何进入可视化界面的可以点这
RabbitMQ之Exchange、Queue参数详解2
2.2接下来是三个参数,也就是加上了是否持久化,同时保留先前两个参数的exchange.0,之前我们已经创建了exchange.0,那么我们再创建一次会怎样
exchangeDeclare(String exchange, String type, boolean durable)

package com.dfyang.rabbitmq.eq0;

import com.dfyang.rabbitmq.RabbitmqConnectionFactory;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;

public class Exchange {

    private static String EXCHANGE_NAME0 = "exchange.0";
    private static String EXCHANGE_NAME1 = "exchange.1";
    private static String EXCHANGE_NAME2 = "exchange.2";

    public static void main(String[] args) throws Exception {
        Connection connection = RabbitmqConnectionFactory.newConnection();
        Channel channel = connection.createChannel();
        //创建一个Exchange,设置名称为exchange.1和类型为direct
        channel.exchangeDeclare(EXCHANGE_NAME0, "direct");
        //创建一个Exchange,设置名称为exchange.1和类型为direct,持久化为false
        channel.exchangeDeclare(EXCHANGE_NAME1, "direct", false);
        //创建一个Exchange,设置名称为exchange.2和类型为direct,持久化为true
        channel.exchangeDeclare(EXCHANGE_NAME2, "direct", true);
        channel.close();
        connection.close();
    }
}

运行成功,并没有报错,因为只要你设置的的设置是一样的,那么就不会报错,如果设置的不一样,那么就会报错,后面会进行验证

这里我们发现exchange.2多了一个D标识,这个D是durable也就是持久化,而exchange.0没有持久化,也就是默认非持久化
RabbitMQ之Exchange、Queue参数详解3
接下来验证这个持久化有什么作用
关闭rabbitmq
rabbitmqctl stop_app
启动rabbitmq
rabbitmqctl start_app
重新进入可视化界面,Exchange就只剩下持久化的了
RabbitMQ之Exchange、Queue参数详解4
2.3接下来是五个参数的
多了两个参数,autoDelete和arguments
exchangeDeclare(String exchange, String type, boolean durable, boolean autoDelete, Map arguments)

下面创建了两个Exchange
exchange.3自动删除为false
exchange.4自动删除为true
由于这里是没有绑定Queue的,那么exchange.4将在创建后就被删除掉?

package com.dfyang.rabbitmq.eq0;

import com.dfyang.rabbitmq.RabbitmqConnectionFactory;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;

public class Exchange {

    private static String EXCHANGE_NAME0 = "exchange.3";
    private static String EXCHANGE_NAME1 = "exchange.4";

    public static void main(String[] args) throws Exception {
        Connection connection = RabbitmqConnectionFactory.newConnection();
        Channel channel = connection.createChannel();
        //创建一个Exchange,设置名称为exchange.3和自动删除为false
        channel.exchangeDeclare(EXCHANGE_NAME1, "direct", false, false, null);
        //创建一个Exchange,设置名称为exchange.4和自动删除为true
        channel.exchangeDeclare(EXCHANGE_NAME1, "direct", false, true, null);
        channel.close();
        connection.close();
    }
}

执行上面的代码
RabbitMQ之Exchange、Queue参数详解5
exchange.4还活的好好的,这是因为我们必须在绑定Queue之后再失去绑定才会被删除,否则为什么不直接抛异常,接下来进行验证
下面直接通过可视化工具创建一个名称为queue.4的Queue
RabbitMQ之Exchange、Queue参数详解6
点击添加之后,点击queue.3进行绑定,输入exchange.3以及RoutingKey(下一节会细讲),点击bind
RabbitMQ之Exchange、Queue参数详解7
我们可以看到已经建立了Binding
RabbitMQ之Exchange、Queue参数详解8
那么我们点击Unbind,发现exchange.4没了
RabbitMQ之Exchange、Queue参数详解9
下面来看看第五个参数arguments的作用,这里依旧是使用可视化工具创建,后一节会使用很多java代码
再我们使用可视化创建Exchange时下面的Arguments提供了一个Alternate exchange,这就是一个arguments(这里只会展示这一个)
RabbitMQ之Exchange、Queue参数详解10
alternate-exchange:如下图,如果我们设置Exchange0的alternate-exchange为Exchange1,那么当Producer发送RoutingKey为test1的消息,Exchange0由于路由不到匹配的队列,会将消息发送给Exchange1进行路由
RabbitMQ之Exchange、Queue参数详解11
上面那张图我们创建了test.exchange.0,接下来创建test.exchange.1
RabbitMQ之Exchange、Queue参数详解12
然后创建test.queue.0和test.queue.1两个队列
RabbitMQ之Exchange、Queue参数详解13
将test.exchange.0绑定test.queue.0
RabbitMQ之Exchange、Queue参数详解14
将test.exchange.1绑定test.queue.1
RabbitMQ之Exchange、Queue参数详解15
点击test.exchange.0来发布一条消息,之一RoutingKey为test.1,也就是test.exchange.0路由不到匹配的Queue,将交给test.exchange.1进行路由,路由到匹配的test.queue.1
RabbitMQ之Exchange、Queue参数详解16
结果我们发现test.queue.1多了一条消息
RabbitMQ之Exchange、Queue参数详解17
2.4接下来是六个参数的
internal:是否内置的,如果为true,只能通过Exchange到Exchange
也就是该Producer无法直接将消息发送给该Exchange,只能将消息发送给一个Exchange再路由到该Exchange
RabbitMQ之Exchange、Queue参数详解18
直接使用可视化界面创建Exchange0设置internal为true
我们发现根本就没有publish这一功能,也就是我们无法通过Producer发布消息到该Exchange上
RabbitMQ之Exchange、Queue参数详解19
创建一个Queue0
RabbitMQ之Exchange、Queue参数详解20
绑定其与Exchange0的关系
RabbitMQ之Exchange、Queue参数详解21
创建一个Exchange1
RabbitMQ之Exchange、Queue参数详解22
绑定Exchange1与Exchange0的关系
RabbitMQ之Exchange、Queue参数详解23
使用Exchange1发送一条RoutingKey为test的消息,消息将被发送到Exchange0,再到Queue0
RabbitMQ之Exchange、Queue参数详解24
结果如下,至此,Exchange的6个参数全部讲解
RabbitMQ之Exchange、Queue参数详解25
2.5讲解完Exchange的参数,再来看Queue的参数,就会发现只有一个exclusive未讲
queueDeclare(String queue, boolean durable, boolean exclusive, boolean autoDelete,
Map arguments

exclusive:是否排他,如果未true,则只在第一次创建它的Connection中有效,当Connection关闭,该Queue也会被删除

在执行完下面代码,查看可视化界面,发现queue中并没有exclusive.queue,因为在connection关闭后,该queue也会自动删除

package com.dfyang.rabbitmq.eq1;

import com.dfyang.rabbitmq.RabbitmqConnectionFactory;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;

public class Exchange {
    private static String QUEUE_NAME0 = "exclusive.queue";

    public static void main(String[] args) throws Exception {
        Connection connection = RabbitmqConnectionFactory.newConnection();
        Channel channel = connection.createChannel();
        channel.queueDeclare(QUEUE_NAME0, true, true, false, null);
        channel.close();
        connection.close();
    }
}

修改代码,让代码一直听着

package com.dfyang.rabbitmq.eq1;

import com.dfyang.rabbitmq.RabbitmqConnectionFactory;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;

public class Exchange {
    private static String QUEUE_NAME0 = "exclusive.queue";

    public static void main(String[] args) throws Exception {
        Connection connection = RabbitmqConnectionFactory.newConnection();
        Channel channel = connection.createChannel();
        channel.queueDeclare(QUEUE_NAME0, true, true, false, null);
        Thread.sleep(100000);
        channel.close();
        connection.close();
    }
}

打开可视化界面,点击exclusive.queue,再点击删除
翻译为:无法获得对锁定队列“独占”的独占访问。队列’在vhost ‘/’。它可以最初在另一个连接上声明,或者独占属性值与原始声明值不匹配。
RabbitMQ之Exchange、Queue参数详解26

完!

Linux安装RabbitMQ
RabbitMQ之Exchange类型详解

勿删,copyright占位
分享文章到微博
分享文章到朋友圈

上一篇:SAP 中各种分摊分配方法

下一篇:java8补充——函数式编程、新增时间类函数

您可能感兴趣

  • RabbitMQ 如何实现对同一个应用的多个节点进行广播

    1.背景 了解过RabbitMQ的Fanout模式,应该知道它原本的Fanout模式就是用来做广播的。但是它的广播有一点区别,来回顾下它的含义:Fanout类型没有路由键的概念,只要队列绑定到了改exchange上面,就会接收到所有的消息。 使用过程一般就是先new 出一个Fanout类型的交换机,然后往这个交换机上绑定多个队列queue,不同的消费者各自监听不同的队列,这就实现了广播效果,...

  • 17 个方面,全面对比 Kafka、RabbitMQ、RocketMQ、ActiveMQ 各自的优缺点

    来源:http://t.cn/RVDWcfe 本文将从,Kafka、RabbitMQ、ZeroMQ、RocketMQ、ActiveMQ 17 个方面综合对比作为消息队列使用时的差异。 一、资料文档 Kafka: 中。 有kafka作者自己写的书,网上资料也有一些。 rabbitmq: 多。 有一些不错的书,网上资料多。 zeromq: 少。 没有专门写zeromq的书,网上的资料多是一些代码...

  • 深入原理64式:31 rabbitmq知识总结

    目标: 整理rabbitmq知识,主要包含如下内容: 1、基础 2、集群 3、综合 4、数据丢失 5、原理 一 基础 1 RabbitMQ 中的 broker 是指什么?cluster 又是指什么? 1)broker是erlang node逻辑分组,node上运行rabbitmq应用 2)cluster是在broker基础上,增加node之间共享元数据的约束 2 什么是元数据?元数据分为哪些...

  • 17 个方面,综合对比 Kafka、RabbitMQ、RocketMQ、ActiveMQ

    点击上方"IT牧场",选择"设为星标"技术干货每日送达! 来源:http://t.cn/RVDWcfe 一、资料文档 二、开发语言 三、支持的协议 四、消息存储 五、消息事务 六、负载均衡 七、集群方式 八、管理界面 九、可用性 十、消息重复 十一、吞吐量TPS 十二、订阅形式和消息分发 十三、顺序消息 十四、消息确认 十五、消息回溯 十六、消息重试 十七、并发度 本文将从,Kafka、Ra...

  • Spring cloud集成Rabbitmq

    1、配置pom org.springframework.boot spring-boot-starter-amqp 2.2.0.RELEASE 2、yml配置 spring: #rabbit mq rabbitmq: host: 192.168.1.146 port: 5672 username: guest password: guest 3、连接、交换器、队列等设置...

  • RabbitMQ基础介绍

    转自 https://www.jianshu.com/p/e55e971aebd8 本文对rabbitmq基础介绍,完全是为了下一篇rabbitmq性能测试做准备,让读者去了解我们需要测试的是什么样一个“东西”。 引言 你是否遇到过两个(多个)系统间需要通过定时任务来同步某些数据?你是否在为异构系统的不同进程间相互调用、通讯的问题而苦恼、挣扎?如果是,那么恭喜你,消息服务让你可以很轻松地解决...

  • RabbitMQ更多应用

    转自:http://www.sohu.com/a/280203461_411876 我是在解决分布式事务的一致性问题时了解到的RabbitMQ,当时主要是要基于RabbitMQ来实现我们分布式系统之间对有事务可靠性要求的系统间通信。 提到RabbitMQ,不难想到的几个关键字:消息中间件、消息队列。当时在大学学习操作系统这门课,消息队列不难想到生产者消费者模式。 (PS:操作系统这门课程真的...

  • 17 个方面,综合对比 Kafka、RabbitMQ、RocketMQ、ActiveMQ 四个分布式消息队列

    点击上方肉眼品世界, 右上角选择“设为星标 深度价值体系传递 来源:http://t.cn/RVDWcfe 本文将从,Kafka、RabbitMQ、ZeroMQ、RocketMQ、ActiveMQ 17 个方面综合对比作为消息队列使用时的差异。 一、资料文档 Kafka: 中。 有kafka作者自己写的书,网上资料也有一些。 rabbitmq: 多。 有一些不错的书,网上资料多。 zerom...

华为云40多款云服务产品0元试用活动

免费套餐,马上领取!
CSDN

CSDN

中国开发者社区CSDN (Chinese Software Developer Network) 创立于1999年,致力为中国开发者提供知识传播、在线学习、职业发展等全生命周期服务。