1.声明
当前内容用于本人学习和使用当前的Headers Exchange,当前内容主要包括Headers Exchange的概念和基本使用
2.Headers Exchange的介绍
当前内容来源于:RabbitMQ官方文档
-
标头交换旨在用于在多个属性上路由,这些属性比路由键更容易表示为消息标头。标头交换忽略路由键属性。相反,用于路由的属性取自headers属性。如果标头的值等于绑定时指定的值,则认为消息匹配。
-
可以使用多个标题进行匹配,将队列绑定到标题交换。在这种情况下,代理需要从应用程序开发者那里获得另一条信息,即,它是否应考虑具有任何匹配的标头的消息,或全部匹配的标头?这就是“ x-match”绑定参数的作用。当“ x-match”参数设置为“ any”时,仅一个匹配的标头值就足够了。或者,将“ x-match”设置为“ all”要求所有值必须匹配。
-
标头交换可以看作是“类固醇的直接交换”。由于它们基于标头值进行路由,因此可以将它们用作直接交换,而路由密钥不必是字符串。例如,它可以是整数或哈希(字典)。
-
请注意,以字符串x-开头的标头 将不用于评估匹配项。
从上面的描述中发现
- 我们使用Headers Exchange的时候的匹配到Queue的规则是headers中的参数,只要参数匹配即可实现消息入列
- 使用Headers Exchange的时候匹配规则和当前的route key无关
- 可以使用x-match参数方式设定匹配规则
- 可以使用x-开头,即上面的描述
3.测试当前的Headers Exchange的key=value方式匹配
1.创建headers Exchange
2.创建三个基本队列
3.将queue通过指定规则绑定到exchange上面
这里的bind的时候我们只要写queue和arguments即可
4.编写消息生产者
public class HeadersTestMessageSender {
private final static String QUEUE_NAME = "headersTest";// 这个随便写
String argvs[] = { "q1", "q2", "q3" };
@Test
public void testSender() {
RabbitMqUtils mqUtils = new RabbitMqUtils();
for (int i = 0; i < 10; i++) {
BasicProperties.Builder builder = new BasicProperties.Builder();
Map<String, Object> headers = new HashMap<String, Object>();
String header = argvs[i % argvs.length];
headers.put("id", header);
builder.headers(headers);
BasicProperties props = builder.build();
mqUtils.send("headersTest", "*", true, props, ("你好,世界!" + i + "[id=" + header+"]"));
}
}
5.编写消息消费者
public class HeadQ1Receiver {
private final static String QUEUE_NAME = "headQ1";
public static void main(String[] args) throws Exception {
RabbitMqUtils mqUtils = new RabbitMqUtils();
mqUtils.reciver(QUEUE_NAME, true, (consumerTag, delivery) -> {
System.out.println("【headQ1】==>" + new String(delivery.getBody(), "utf-8"));
});
}
}
public class HeadQ2Receiver {
private final static String QUEUE_NAME = "headQ2";
public static void main(String[] args) throws Exception {
RabbitMqUtils mqUtils = new RabbitMqUtils();
mqUtils.reciver(QUEUE_NAME, true, (consumerTag, delivery) -> {
System.out.println("【headQ2】==>" + new String(delivery.getBody(), "utf-8"));
});
}
}
public class HeadQ3Receiver {
private final static String QUEUE_NAME = "headQ3";
public static void main(String[] args) throws Exception {
RabbitMqUtils mqUtils = new RabbitMqUtils();
mqUtils.reciver(QUEUE_NAME, true, (consumerTag, delivery) -> {
System.out.println("【headQ3】==>" + new String(delivery.getBody(), "utf-8"));
});
}
}
6.启动三个消息消费者
7.执行消息生产者并查看结果
发现测试成功,说明只要key=value
就可以实现消息的入队,并实现消费
4.测试x-match
这个用于匹配当前的操作,例如OR或者AND
直接创建队列headQ4,然后执行以下操作
1.创建两个队列
2.为这两个队列绑定到exchange
headQ4绑定参数为:flag=true、id=q1、x-match=any
headQ5绑定参数为:flag=true、id=q1
3.创建对应的类,然后启动所有的队列,并执行操作发现结果
这个是headQ4的结果,说明使用x-match=any
,表示参数之间使用or的关系匹配,只需要满足其中一个就可以匹配
Q5的结果中没有数据,说明默认就是使用x-match=all
,必须所有的参数都一致才能实现入队操作
5.总结
1.当前的Headers Exchange匹配方式就是只要实现Headers中的参数匹配即可,这个方式和前面的完全不一样,将匹配提高到了arguements上面了
2.该方式主要就是匹配arguements和当前的route key没关系
3.默认情况下配置这个x-match是在绑定queue到exchange中设定的参数
,并且如果不添加x-match默认就是使用all方式处理
以上纯属个人见解,如有问题请联系本人!