RabbitMQ 的四种 Exchange

RabbitMQ 的四种 Exchange

在了解这些消息模式的时候,引入了一个概念 Exchange(交换机)

发布订阅里面有对这个概念做解释:

RabbitMQ消息传递模型中的核心思想是生产者从不将任何消息直接发送到队列。实际上,生产者经常甚至根本不知道是否将消息传递到任何队列。
相反,生产者只能将消息发送到交换机。交流是一件非常简单的事情。一方面,它接收来自生产者的消息,另一方面,将它们推入队列。交易所必须确切知道如何处理收到的消息。是否应将其附加到特定队列?是否应该将其附加到许多队列中?还是应该丢弃它。规则由交换机类型定义 

而 Exchange 的类型有下面四种:

  • direct(直连交换机):将队列绑定到交换机,消息的 routeKey 需要与队列绑定的 routeKey 相同。
  • fanout (扇形交换机):不处理 routeKey ,直接把消息转发到与其绑定的所有队列中。
  • topic(主题交换机):根据一定的规则,根据 routeKey 把消息转发到符合规则的队列中,其中 # 用于匹配符合一个或者多个词(范围更广), * 用于匹配一个词。
  • headers (头部交换机):根据消息的 headers 转发消息而不是根据 routeKey 来转发消息, 其中 header 是一个 Map,也就意味着不仅可以匹配字符串类型,也可以匹配其他类型数据。 规则可以分为所有键值对匹配或者单一键值对匹配
消息模式  交换机
Simple Work Queue (简单工作队列) Work Queues (工作队列)    空交换机
Publish/Subscribe (发布订阅模式)  fanout (扇形交换机)
Routing(路由模式)  direct (直连交换机)
Topics(主题模式)  topic(主题交换机)

 

 

一.headers 头部交换机

简介

首部交换机和扇形交换机都不需要路由键routingKey,交换机时通过Headers头部来将消息映射到队列的,有点像HTTP的Headers,Hash结构中要求携带一个键“x-match”,这个键的Value可以是any或者all,这代表消息携带的Hash是需要全部匹配(all),还是仅匹配一个键(any)就可以了。相比直连交换机,首部交换机的优势是匹配的规则不被限定为字符串(string)而是Object类型。

  • any: 只要在发布消息时携带的有一对键值对headers满足队列定义的多个参数arguments的其中一个就能匹配上,注意这里是键值对的完全匹配,只匹配到键了,值却不一样是不行的;
  • all:在发布消息时携带的所有Entry必须和绑定在队列上的所有Entry完全匹配

这里写图片描述

 

1.1生产者

package com.exchang.headers;

import com.rabbitmq.client.*;

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

/**
 * 消息生产者
 */
public class OneProducer {
    private static final String EXchang_Name ="rabbit:mq05:exchange:e01";

    public static void main(String[] args){
        try{
            ConnectionFactory factory = new ConnectionFactory();
            factory.setHost("localhost");

            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!";
            channel.basicPublish(EXchang_Name, "", properties.build(), message.getBytes("UTF-8"));
            channel.close();
            connection.close();
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

1.2消费者

package com.exchang.headers;

import com.rabbitmq.client.*;

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

public class MuitiConsumerOne {

    private static final String EXchang_Name ="rabbit:mq05:exchange:e01";
    private static final String Queue_Name_01="rabbit:mq05:queue:q01";


    public static void main(String[] args){
        try{
            ConnectionFactory factory = new ConnectionFactory();
            factory.setHost("localhost");

            Connection connection = factory.newConnection();
            Channel channel = connection.createChannel();
            channel.exchangeDeclare(EXchang_Name, BuiltinExchangeType.HEADERS);
            channel.queueDeclare(Queue_Name_01,true,false,false,null);


            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(Queue_Name_01, EXchang_Name, "", arguments);
            Consumer  consumer = new DefaultConsumer(chan
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值