RabbitMQ入门教程(九):首部交换机Headers
来源:互联网 发布:mysql trigger debug 编辑:程序博客网 时间:2024/06/08 10:26
简介
首部交换机和扇形交换机都不需要路由键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(); }}
消费者
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); }}
运行结果
先运行消费者,再运行生产者。
// 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");
直连接和首部类型的比较
绑定规则不同:直连接是一个简单的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消息队列-通过Headers模式分发消息
- RabbitMQ入门教程(五):扇形交换机发布/订阅(Publish/Subscribe)
- rabbitmq 交换模式-Headers
- rabbitmq 交换模式-Headers
- RabbitMQ学习之:(九)Headers Exchange (转贴+我的评论)
- RabbitMQ之路由 headers方式
- RabbitMq中的交换机
- rabbitMq 交换机介绍
- RabbitMQ交换机的理解
- 3-RabbitMQ交换机- fanout
- rabbitMQ的交换机类型
- 4-RabbitMQ交换机-direct
- 5-RabbitMQ交换机-topic
- java-rabbitmq-交换机介绍
- RabbitMQ四种交换机
- rabbitMq 交换机介绍
- wampserver2.4.9多站点配置笔记
- Git 学习(二)
- codeforces 535C(二分)
- 对事务的理解
- Oracle之数据库和用户创建-yellowcong
- RabbitMQ入门教程(九):首部交换机Headers
- 结合redis设计与实现的redis源码学习-13-AOF持久化(aof.c/bio.h)
- 三天怼完Scala---Scala自学笔记
- Python——加密后的China
- 文件系统的特殊权限
- [持续更新]带你一步一步学习Android热修复技术
- Eclipse调试以及step into step over step return区别
- Java数据结构和算法之归并排序
- kafka java连接操作