教程说明

  • 本系列教程目录大纲:​​《RabbitMQ系列教程-目录大纲》​​


RabbitMQ交换机之Header类型交换机

4.8.1 简介

关于​​RabbitMQ​​​官网提供的所有交换模式我们都已经介绍完毕了,唯独还有一个​​header​​​类型的交换机没有介绍,那​​header​​类型的交换机又有什么作用呢?

​header​​​类型的​​Exchange​​​与​​Routing​​​有点类似,不同的是,​​header​​​类型的​​Exchange​​​取消了​​Routing Key​​​,使用​​key/value​​来匹配队列

​header​​​的匹配有两种方式,一种是​​all​​​另一种是​​any​​​。这两种方式是在接收端必须要用键值​​"x-mactch"​​来定义。

  • all:代表必须匹配​​Consumer​​端的所有键值对
  • any:代表只要匹配​​Consumer​​端的任意一个键值对即可

《RabbitMQ系列教程-第四章-08-Header类型交换机》_java

4.8.2 生产者

package com.lscl.rabbitmq;

import com.rabbitmq.client.*;
import com.rabbitmq.client.AMQP.BasicProperties.Builder;

import java.util.HashMap;
import java.util.Map;

public class Producer06_Header {

public static void main(String[] args) throws Exception {
// 创建连接和频道
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("192.168.40.132");
factory.setPort(5672);
factory.setUsername("lscl");
factory.setPassword("admin");
factory.setVirtualHost("/lscl");

Connection connection = factory.newConnection();
Channel channel = connection.createChannel();

/*
定义一个交换机为header类型
true:代表持久化
true:代自动删除(没有consumer时自动销毁)
false:代表不是内部使用的交换机
null:传递的参数为null
*/
String exchangeName = "test_header";

// 声明交换机和类型headers
channel.exchangeDeclare(exchangeName, BuiltinExchangeType.HEADERS, true, false, false, null);

String queue = "test_header_queue";
// 定义队列
channel.queueDeclare(queue, true, false, false, null);

// 声明header
Map<String, Object> bindingHeaders = new HashMap<>();
/*
all:代表发送消息时必须匹配header中的所有key/val对
any:代表发送消息时只需要匹配header中的任意一个key/val对
*/
bindingHeaders.put("x-match", "all");
bindingHeaders.put("key1", "147");
bindingHeaders.put("key2", "258");
bindingHeaders.put("key3", "369");

// 将交换机绑定到队列,并指定header信息
channel.queueBind(queue, exchangeName, "", bindingHeaders);

String body = "header....";

// 发送信息携带的header
Map<String, Object> requestHeader = new HashMap<>();
requestHeader.put("key1", "147");
// requestHeader.put("key2", "258");
// requestHeader.put("key3", "369");

// 消息配置对象
Builder properties = new AMQP.BasicProperties.Builder();
properties.headers(requestHeader);

// 将消息直接发送给交换机(携带指定的参数header),让交换机自己根据header条件去转发到指定queue
channel.basicPublish(exchangeName, "", properties.build(), body.getBytes());

channel.close();
connection.close();
}
}

4.8.3 消费者

package com.lscl.rabbitmq;

import java.io.IOException;
import java.util.Hashtable;
import java.util.Map;

import com.rabbitmq.client.*;

public class Consumer11_Header {
public static void main(String[] args) throws Exception {
// 创建连接和频道
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("192.168.40.132");
factory.setPort(5672);
factory.setUsername("lscl");
factory.setPassword("admin");
factory.setVirtualHost("/lscl");

Connection connection = factory.newConnection();
Channel channel = connection.createChannel();

channel.basicConsume("test_header_queue", true, new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {

System.out.println("body:" + new String(body));
}
});

}
}

4.8.4 header类型交换机小结

在​​header​​​类型交换机中,放弃了​​routing key​​​,取而代之的是​​key/value​​​键值对,在Producer绑定队列时指定​​key/value​​​键值对,当Producer发送消息时也会指定一个​​key/value​​​键值对,如果此时的​​key/value​​键值对符合当初绑定队列的键值对,那么消息就可以路由到此队列,反之消息则丢失;

  • ​header​​类型交换机工作原理图:

《RabbitMQ系列教程-第四章-08-Header类型交换机》_java_02