基础术语

  1. Exchange
    交换机,可以理解为一个路由器,交换机会事先通过bindingKey绑定一个或者多个Queue。然后我们发消息时是先把消息发送到交换机,然后交换机再通过你发送消息时指定的routingKey,把消息投放到指定的Queue。
  2. Queue
    队列,作用是存储消息,队列的特性是先进先出,生产者生产消息最终被送到RabbitMQ的内部对象Queue中去,而消费者则是从Queue队列中取出数据。
  3. Binding
    绑定,我们在发送消息到MQ时,是先发送到Exchange的,那么我交换机是怎么知道我需要将这个消息发送到哪个Queue,这就需要将Exchange通过bingdingKey绑定一个或者多个Queue,然后Exchange就会根据路由规则bingdingKey把消息发送到指定的Queue。
    关于以上的三个术语可以用以下这张图概括:

交换机的类型

在上面的图中,交换机值根据类型来决定怎么讲消息放入队列中的,那么我们先看一下交换机的类型。交换机有四种类型, 分别为Direct, topic, headers, Fanout。

  1. Direct-直连交换机
    Direct 是 RabbitMQ 默认的交换机模式,也是最简单的模式。即创建消息队列并绑定交换机时的时候,指定一个 BindingKey。当发送者发送消息的时候,,指定对应的 Key,当 Key 和消息队列的 BindingKey 一致的时候,消息将会被发送到该消息队列中。可以理解为指定的一对一模式,直连交换机。
    场景图:
  2. Java rabbitmq消息订阅配置多个连接绑定交换机 rabbitmq交换机绑定队列_rabbitmq

  3. Topic-主题交换机
    topic这个规则是模糊匹配,可以通过通配符满足一部分规则就可以传送消息。
    发送到主题交换机(topic exchange)的消息不可以携带随意什么样子的路由键(routingKey),它的路由键必须是一个由.(英文的句号)分隔开的词语列表。这些单词随便是什么都可以,但是最好是跟携带它们的消息有关系的词汇。以下是几个推荐的例子:“stock.usd.nyse”, “nyse.vmw”, “quick.orange.rabbit”。词语的个数可以随意,但是不要超过255字节。
    绑定键(bingdingKey)也必须拥有同样的格式。主题交换机背后的逻辑跟直连交换机很相似 —— 一个携带着特定路由键的消息会被主题交换机投递给绑定键与之想匹配的队列。但是它的绑定键和路由键有两个特殊应用方式:
    1 * (星号) 用来表示一个单词.
    2 # (井号) 用来表示任意数量(零个或多个)单词。
    场景图
  4. Java rabbitmq消息订阅配置多个连接绑定交换机 rabbitmq交换机绑定队列_键值对_02

  5. 描述:
    这个例子里,我们发送的所有消息都是用来描述小动物的。发送的消息所携带的路由键是由三个单词所组成的,这三个单词被两个.分割开。路由键里的第一个单词描述的是动物的手脚的利索程度,第二个单词是动物的颜色,第三个是动物的种类。所以它看起来是这样的: ..。
    我们创建了三个绑定:Q1的绑定键为*.orange.*,Q2的绑定键为 * . * .rabbit 和 lazy.# 。
    这三个绑定键被可以总结为:
    Q1 对所有的桔黄色动物都感兴趣。
    Q2 则是对所有的兔子和所有懒惰的动物感兴趣。
    一个携带有 quick.orange.rabbit 的消息将会被分别投递给这两个队列。携带着 lazy.orange.elephant 的消息同样也会给两个队列都投递过去。另一方面携带有 quick.orange.fox 的消息会投递给第一个队列,携带有 lazy.brown.fox 的消息会投递给第二个队列。携带有 lazy.pink.rabbit 的消息只会被投递给第二个队列一次,即使它同时匹配第二个队列的两个绑定。携带着 quick.brown.fox 的消息不会投递给任何一个队列。
    如果我们违反约定,发送了一个携带有一个单词或者四个单词(“orange” or “quick.orange.male.rabbit”)的消息时,发送的消息不会投递给任何一个队列,而且会丢失掉。
    但是另一方面,即使 “lazy.orange.male.rabbit” 有四个单词,他还是会匹配最后一个绑定,并且被投递到第二个队列中。
  6. Fanout-广播交换机
    fanout类型的Exchange路由规则非常简单,它会把所有发送到该Exchange的消息路由到所有与它绑定的Queue中
    场景图
  7. Java rabbitmq消息订阅配置多个连接绑定交换机 rabbitmq交换机绑定队列_发送消息_03

  8. Headers-键值对交换机
    headers类型的Exchange不依赖于routing key与binding key的匹配规则来路由消息,而是根据发送的消息内容中的headers属性进行匹配。
    在绑定Queue与Exchange时指定一组键值对;当消息发送到Exchange时,RabbitMQ会取到该消息的headers(也是一个键值对的形式),对比其中的键值对是否完全匹配Queue与Exchange绑定时指定的键值对;如果完全匹配则消息会路由到该Queue,否则不会路由到该Queue

java中的交换机对象

在java中,spring提供了对应的交换机对象,继承关系如下图:

Java rabbitmq消息订阅配置多个连接绑定交换机 rabbitmq交换机绑定队列_消息发送_04


统一的构造方法如下:

/**
 * Construct a new durable, non-auto-delete Exchange with the provided name.
 * @param name the name of the exchange.
 */
public AbstractExchange(String name) {
	this(name, true, false);
}

/**
 * Construct a new Exchange, given a name, durability flag, auto-delete flag.
 * @param name the name of the exchange.
 * @param durable true if we are declaring a durable exchange (the exchange will
 * survive a server restart)
 * @param autoDelete true if the server should delete the exchange when it is no
 * longer in use
 */
public AbstractExchange(String name, boolean durable, boolean autoDelete) {
	this(name, durable, autoDelete, null);
}

/**
 * Construct a new Exchange, given a name, durability flag, and auto-delete flag, and
 * arguments.
 * @param name the name of the exchange.
 * @param durable true if we are declaring a durable exchange (the exchange will
 * survive a server restart)
 * @param autoDelete true if the server should delete the exchange when it is no
 * longer in use
 * @param arguments the arguments used to declare the exchange
 */
public AbstractExchange(String name, boolean durable, boolean autoDelete, Map<String, Object> arguments) {
	super();
	this.name = name;
	this.durable = durable;
	this.autoDelete = autoDelete;
	if (arguments != null) {
		this.arguments = arguments;
	}
	else {
		this.arguments = new HashMap<String, Object>();
	}
}

其中参数含义如下:
name:交换机的名称
durable:是否持久化,持久化后再重启时这个交换机还会存在
autoDelete:若长期不适用这个交换机是否自动删除
arguments:其他参数,是一个map,目前只知道能设置最高优先级,通过这个key:x-max-priority往map里面塞,其他的设置稍后研究了再补上。

关于在springboot中怎么用,留待下次一一学习