Headers类型Exchange
前面讲过fanout,direct,topic类型的exchange的使用,还有一个headers类型的exchange未提到如何使用它,现在我们就来看看header exchange该如何使用以及在哪些场景下使用这种类型的exchange。
一、Headers
headers exchange主要通过发送的request message中的header进行匹配,其中匹配规则(x-match)又分为all和any:
- all代表必须所有的键值对匹配,
- any代表只要有一个键值对匹配即可。
headers exchange的默认匹配规则(x-match)是any。说明如下:
- 我们使用Headers Exchange的时候的匹配到Queue的规则是headers中的参数,只要参数匹配即可实现消息入列
- 使用Headers Exchange的时候匹配规则和当前的route key无关
- 可以使用x-match参数方式设定匹配规则
- 可以使用x-开头,即上面的描述
架构图如下:

二、通过接口创建header类型的交换机
2.1.生产者
编写生产者代码如下:
package com.augus.header; import com.augus.util.RabbitMQConnectionUtil; import com.rabbitmq.client.AMQP; import com.rabbitmq.client.BuiltinExchangeType; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import org.junit.Test; import java.io.IOException; import java.util.HashMap; import java.util.concurrent.TimeoutException; public class Publisher { public static final String HRADER_EXCHANE = "head-exchange"; public static final String HRADER_QUEUE = "head-queue"; @Test public void publish() throws IOException, TimeoutException { //创建连接 Connection connection = RabbitMQConnectionUtil.getConnection(); //创建channel Channel channel = connection.createChannel(); //构建交换机和队列,并基于header的方式实现绑定 channel.exchangeDeclare(HRADER_EXCHANE, BuiltinExchangeType.HEADERS); //创建交换机,指定交换机的类型 channel.queueDeclare(HRADER_QUEUE,true,false,false,null);//创建队列 HashMap<String, Object> map = new HashMap<>(); /** * "x-match","all" 多个header的key-value要求全部匹配上! * "x-match","any" 多个header的key-value只要可以匹配上一个就可以 */ map.put("x-match","all"); map.put("name","augus"); map.put("age","18"); //绑定方式这里routingKey就不需要了,所以为空 channel.queueBind(HRADER_QUEUE,HRADER_EXCHANE,"",map); //发送消息 //构建添加 HashMap<String, Object> headers = new HashMap<>(); headers.put("name","augus"); headers.put("age","18"); AMQP.BasicProperties props = new AMQP.BasicProperties() .builder() .headers(headers) .build(); channel.basicPublish(HRADER_EXCHANE,"",props,"明天周五了".getBytes()); System.out.println("发送消息成功"); } }
2.2.测试
启动RabbitMQ,上面的生产者x-match值为all,要求发送信息携带的header需要全部匹配,执行发送消息到队列,如下:

先删除创建的队列,然后故意将age这个键改错,由于方式是all,要求全部匹配,执行发送消息到队列,如下队列中并没有消息:

查看队列:

三、通过springboot整合RabbitMQ创建header类型的交换机
3.1.创建交换机绑定队列
在config包下创建HeaderConfig ,让一个header类型的交换机绑定两个队列,分别测试all和any
package com.augus.rabbitmq02.config; import org.springframework.amqp.core.*; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.HashMap; @Configuration public class HeaderConfig { public static final String EXCHANGE_NAME = "head—exchange"; public static final String QUEUE_NAME1 = "head-queue01"; public static final String QUEUE_NAME2 = "head-queue02"; /** * 创建交换机 * @return */ @Bean public HeadersExchange headersExchange(){ return ExchangeBuilder.headersExchange(EXCHANGE_NAME).build(); } @Bean public Queue queue01(){ return QueueBuilder.durable(QUEUE_NAME1).build(); } @Bean public Queue queue02(){ return QueueBuilder.durable(QUEUE_NAME2).build(); } /** * 交换机和队列1绑定 * @param headersExchange 交换机 * @param queue01 队列1 * @return */ @Bean public Binding headerBind01(HeadersExchange headersExchange,Queue queue01){ HashMap<String, Object> map = new HashMap<>(); map.put("x-match","all"); map.put("name", "jack"); map.put("age", "23"); return BindingBuilder.bind(queue01).to(headersExchange).whereAll(map).match(); } /** * 交换机和队列2绑定 * @param headersExchange 交换机 * @param queue02 队列2 * @return */ @Bean public Binding headerBind02(HeadersExchange headersExchange,Queue queue02){ HashMap<String, Object> map = new HashMap<>(); map.put("x-match","any"); map.put("name", "augus"); map.put("age", "18"); return BindingBuilder.bind(queue02).to(headersExchange).whereAny(map).match(); } }
3.2.编写生产者
创建两个生产者分别给两个队列发送消息,如下:
package com.augus.rabbitmq02; import com.augus.rabbitmq02.config.HeaderConfig; import org.junit.jupiter.api.Test; import org.springframework.amqp.AmqpException; import org.springframework.amqp.core.Message; import org.springframework.amqp.core.MessagePostProcessor; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest public class HeaderPublisher { @Autowired private RabbitTemplate rabbitTemplate; @Test public void send1(){ rabbitTemplate.convertAndSend(HeaderConfig.HEADER_EXCHANGE, "", "暮霭程程楚天阔", new MessagePostProcessor() { @Override public Message postProcessMessage(Message message) throws AmqpException { //设置消息的关联ID message.getMessageProperties().setHeader("name","jack"); message.getMessageProperties().setHeader("age","23"); return message; } }); System.out.println("消息发送成功!!!"); } @Test public void send2(){ rabbitTemplate.convertAndSend(HeaderConfig.HEADER_EXCHANGE, "", "念去去千里烟波", new MessagePostProcessor() { @Override public Message postProcessMessage(Message message) throws AmqpException { //设置消息的关联ID message.getMessageProperties().setHeader("name","augus"); //故意只写一个条件 //message.getMessageProperties().setHeader("age","18"); return message; } }); System.out.println("消息发送成功!!!"); } }

浙公网安备 33010602011771号