RabbitMQ入门教程(九):首部交换机Headers
原文:RabbitMQ入门教程(九):首部交换机Headers
版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。
分享一个朋友的人工智能教程。比较通俗易懂,风趣幽默,感兴趣的朋友可以去看看。
简介
首部交换机和扇形交换机都不需要路由键routingKey,交换机时通过Headers头部来将消息映射到队列的,有点像HTTP的Headers,Hash结构中要求携带一个键“x-match”,这个键的Value可以是any或者all,这代表消息携带的Hash是需要全部匹配(all),还是仅匹配一个键(any)就可以了。相比直连交换机,首部交换机的优势是匹配的规则不被限定为字符串(string)而是Object类型。
- any: 只要在发布消息时携带的有一对键值对headers满足队列定义的多个参数arguments的其中一个就能匹配上,注意这里是键值对的完全匹配,只匹配到键了,值却不一样是不行的; 
- all:在发布消息时携带的所有Entry必须和绑定在队列上的所有Entry完全匹配 
生产者
public class Producer {
    @Test
    public void testBasicPublish() throws IOException, TimeoutException {
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("127.0.0.1");
        factory.setPort(AMQP.PROTOCOL.PORT);
        factory.setUsername("mengday");
        factory.setPassword("mengday");
        Connection connection = factory.newConnection();
        Channel channel = connection.createChannel();
        Map<String, Object> heardersMap = new HashMap<String, Object>();
        heardersMap.put("api", "login");
        heardersMap.put("version", 1.0);
        heardersMap.put("radom", UUID.randomUUID().toString());
        AMQP.BasicProperties.Builder properties = new AMQP.BasicProperties().builder().headers(heardersMap);
        String message = "Hello RabbitMQ!";
        String EXCHANGE_NAME = "exchange.hearders";
        channel.basicPublish(EXCHANGE_NAME, "", properties.build(), message.getBytes("UTF-8"));
        channel.close();
        connection.close();
    }
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
消费者
public class Consumer1 {
    @Test
    public void testBasicConsumer1() throws Exception{
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("127.0.0.1");
        factory.setPort(AMQP.PROTOCOL.PORT);    // 5672
        factory.setUsername("mengday");
        factory.setPassword("mengday");
        Connection connection = factory.newConnection();
        Channel channel = connection.createChannel();
        String EXCHANGE_NAME = "exchange.hearders";
        channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.HEADERS);
        String queueName = channel.queueDeclare().getQueue();
        Map<String, Object> arguments = new HashMap<String, Object>();
        arguments.put("x-match", "any");
        arguments.put("api", "login");
        arguments.put("version", 1.0);
        arguments.put("dataType", "json");
        // 队列绑定时需要指定参数,注意虽然不需要路由键但仍旧不能写成null,需要写成空字符串""
        channel.queueBind(queueName, EXCHANGE_NAME, "", arguments);
        Consumer consumer = new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                String message = new String(body, "UTF-8");
                System.out.println(message);
            }
        };
        channel.basicConsume(queueName, true, consumer);
        Thread.sleep(100000);
    }
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
运行结果
先运行消费者,再运行生产者。
// all:匹配失败,缺少{"dataType", "json"}
Map<String, Object> heardersMap = new HashMap<String, Object>();
heardersMap.put("api", "login");
heardersMap.put("version", 1.0);
// all:匹配成功,生产者多发送一个head没关系
Map<String, Object> heardersMap = new HashMap<String, Object>();
heardersMap.put("api", "login");
heardersMap.put("version", 1.0);
heardersMap.put("dataType", "json");
heardersMap.put("ext", false);
Map<String, Object> arguments = new HashMap<String, Object>();
arguments.put("x-match", "all");
arguments.put("api", "login");
arguments.put("version", 1.0);
arguments.put("dataType", "json");
//------------------------------------------
// any: 匹配成功,只要有一个键值对能满足队列的arguments即可
Map<String, Object> heardersMap = new HashMap<String, Object>();
heardersMap.put("api", "login");
Map<String, Object> arguments = new HashMap<String, Object>();
arguments.put("x-match", "any");
arguments.put("api", "login");
arguments.put("version", 1.0);
arguments.put("dataType", "json");
// any: 匹配失败,键值对中的key和value必须全部匹配上
Map<String, Object> heardersMap = new HashMap<String, Object>();
heardersMap.put("api", "regist");
Map<String, Object> arguments = new HashMap<String, Object>();
arguments.put("x-match", "any");
arguments.put("api", "login");
arguments.put("version", 1.0);
arguments.put("dataType", "json");
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
直连接和首部类型的比较
- 绑定规则不同:直连接是一个简单的String;而首部是键值对Entry,而且键值对的value可以是任意类型Object 
- 绑定个数不同:直连接一次只能绑定一个字符串,如果想绑定多个字符串就需要绑定多次或者循环调用queueBind()方法来绑定多次;而首部类型直接可以往Map中添加多个实体Entry即可 
- 映射规则不同:直连接只需要比较路由键是否相等即可,而首部类型除了比较value还要比较key,因为首部类型是Entry类型,需要同时比较key和value,而且首部类型还可以通过x-match来控制匹配的条件,all:需要匹配所有Entry,相当于SQL中的 and操作,any:只需要匹配上一个Entry即可,相当于SQL中的or操作 
- 直连接适用于计较简单的路由,而首部类型相比直连接匹配规则更强大 
分享一个朋友的人工智能教程。比较通俗易懂,风趣幽默,感兴趣的朋友可以去看看。
我的微信公众号:
RabbitMQ入门教程(九):首部交换机Headers的更多相关文章
- RabbitMQ入门教程(七):主题交换机Topics
		原文:RabbitMQ入门教程(七):主题交换机Topics 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog. ... 
- RabbitMQ入门教程(五):扇形交换机发布/订阅(Publish/Subscribe)
		原文:RabbitMQ入门教程(五):扇形交换机发布/订阅(Publish/Subscribe) 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. ... 
- RabbitMQ入门教程(十四):RabbitMQ单机集群搭建
		原文:RabbitMQ入门教程(十四):RabbitMQ单机集群搭建 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://b ... 
- RabbitMQ入门教程(十三):虚拟主机vhost与权限管理
		原文:RabbitMQ入门教程(十三):虚拟主机vhost与权限管理 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://b ... 
- RabbitMQ入门教程(十一):消息属性Properties
		原文:RabbitMQ入门教程(十一):消息属性Properties 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://b ... 
- RabbitMQ入门教程(十):队列声明queueDeclare
		原文:RabbitMQ入门教程(十):队列声明queueDeclare 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https:// ... 
- RabbitMQ入门教程(四):工作队列(Work Queues)
		原文:RabbitMQ入门教程(四):工作队列(Work Queues) 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https:/ ... 
- RabbitMQ入门教程(三):Hello World
		原文:RabbitMQ入门教程(三):Hello World 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog. ... 
- RabbitMQ入门教程(二):简介和基本概念
		原文:RabbitMQ入门教程(二):简介和基本概念 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn ... 
随机推荐
- HDU 2859—Phalanx(DP)
			Time Limit:5000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Description Today i ... 
- R_Studio(学生成绩)使用主成分分析实现属性规约
			对11_1_4.csv成绩表进行主成分分析处理 setwd('D:\\data') list.files() #读取数据 dat=read.csv(file="11_1_4.csv" ... 
- 半径R覆盖最多点
			struct point { double x, y; }; point p[N]; struct alpha { double v; bool flag; bool friend operator ... 
- 动态数组C语言实现
			/* * DynamicArray.h * * Created on: 2019年7月22日 * Author: Jarvis */ #ifndef SRC_DYNAMICARRAY_H_ #defi ... 
- C++ 操作符重载实践 & java没有重载操作符的思路
			实践如下: #include <iostream> using namespace std; class Book{ private: int page; public: Book(int ... 
- gromacs2018使用踩坑记--insert-molecules
			1] gmx插入分子[ -f [<.gro / .g96 / ...>] ] [ -ci [<.gro / .g96 / ...>] ] [ -ip [<.dat> ... 
- 自定义View饼状图的绘制
			package com.loaderman.customviewdemo; import android.content.Context; import android.graphics.Canvas ... 
- mysql中文乱码 常见编码问题解决方法分享
			我是真的服了 mysql默认字符不是utf-8也不是GBK而是拉丁文字?? 在增删数据时 “中文字符” 老是乱码不停!害得我浪费不少时间在这上面 为各位之后不走坑 再此留下解决方法 若想进一步了解编码 ... 
- ControlTemplate in WPF —— ItemsControl
			<ItemsControl Margin=" ItemsSource="{Binding Source={StaticResource myTodoList}}"& ... 
- nodejs 框架 中文express 4.xxx中文API手册
			介于最近express 中文文档比较难找的现状,特地找了一个,供大家学习思考 Express 4.x API express 翻译 api文档 中文 -- express() expre ... 
