RabbitMQ Exchange 交换机

Exchange 交换机: 接收消息,并根据路由键转发消息到所绑定的队列。

在这里插入图片描述
交换机属性

属性名称介绍
name交换机名称
type交换机类型 :direct,topic,fanout,headers
Durability是否进行持久化
Auto Delete当最后一个绑定到Exchange上的队列删除后,自动删除
Internal当前Exchange是否用于RabbitMQ内部使用,默认为False。(大部分不需要)
Arguments扩展参数,用户扩展AMQP协议,定制化使用

Exchange Type 简介:

type介绍
Direct Exchange所有发送到Direct Exchange的消息被转发到RouteKey中指定的Queue
Topic Exchange所有发送到Topic Exchange的消息被转发到所有关心RouteKey中指定的Topic的Queue上。
Exchange 将RoutKey和某Topic进行模糊匹配,此时队列需要绑定一个Topic
Fanout Exchange不处理路由键,只需要简单的将队列绑定到交换机上。发送到交换机上都会转发到与该交换机绑定的所有队列上。Fanout 交换机发消息是最快的。
Header Exchange通过消息头进行路由(不常用)

Exchange Type 详解:

Direct Exchange

介绍

Direct Exchange : 所有发送到Direct Exchange的消息被转发到RouteKey中指定的Queue
在这里插入图片描述
     注意:Direct模式可以使用RabbitMQ自带的Exchange:default Exchange,所以不需要将Exchange进行任何绑定(bingding)操作,消息传递时,RouteKey必须完全匹配才会被队列接收,否则会被抛弃。

代码实现
public class Consumer {

    public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
        //1,创建工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("localhost");
        connectionFactory.setPort(5672);
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");
        //2,获取连接
        Connection connection = connectionFactory.newConnection();
        //3,通过connection创建一个channel
        Channel channel = connection.createChannel();
        //4,exchange, routingkey, queue, 并将queue和交换机绑定
        String queueName = "test001";
        //设置交换机
        String exchangeName = "exchange001";
        String exchangeType = "direct";
        String routingKey = "routingKey001";

        //声明一个交换机
        channel.exchangeDeclare(exchangeName, exchangeType, true, false, false, null);
        //声明一个队列
        channel.queueDeclare(queueName, true, false, false, null);
        //建立关系
        channel.queueBind(queueName, exchangeName, routingKey);

        //5,创建消费者//
        QueueingConsumer queueingConsumer = new QueueingConsumer(channel);

        //6,设置channel
        channel.basicConsume(queueName, true, queueingConsumer);

        //7,获取消息
        while (true){
            QueueingConsumer.Delivery delivery = queueingConsumer.nextDelivery();
            String msg = new String(delivery.getBody());
            System.out.println(msg);
        }
    }
}

//生产者
public class producer {

    public static void main(String[] args) throws IOException, TimeoutException {
        //创建工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("localhost");
        connectionFactory.setPort(5672);
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");
        //获取连接
        Connection connection = connectionFactory.newConnection();
        //通过connection创建一个channel
        Channel channel = connection.createChannel();

        String exchangeName = "exchange001";
        String routingKey = "routingKey0011";

        //发布消息
        for(int i = 0; i < 5; i++){
            String msg = "hello rabbitmq " + i;
            //1.exchange  2.routing key
            //默认交换器隐式绑定到每个队列,其路由键等于队列名. 如果没有队列名,则会被删除
            channel.basicPublish(exchangeName, routingKey, null, msg.getBytes());
        }
        channel.close();
        connection.close();

    }
}


Topic Exchange

介绍

Topic Exchange: 所有发送到Topic Exchange的消息被转发到所有关心RouteKey中指定的Topic的Queue上。Exchange 将RoutKey和某Topic进行模糊匹配,此时队列需要绑定一个Topic。
在这里插入图片描述
      注意:可以使用通配符进行模糊匹配。

通配符通配符简介
#匹配一个词或多个词。eg: log.# 可以匹配到 log.info.add
*只能匹配一个词。 eg: log.* 只能匹配到 log.info
代码实现
import com.rabbitmq.client.*;
import javax.security.auth.callback.Callback;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
 * 消费者类
 */
public class ConsumerTopic {

    public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
        //1,创建工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("localhost");
        connectionFactory.setPort(5672);
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");
        //2,获取连接
        Connection connection = connectionFactory.newConnection();
        //3,通过connection创建一个channel
        Channel channel = connection.createChannel();
        //4,exchange, routingkey, queue, 并将queue和交换机绑定
        String queueName = "topic001";
        //设置交换机
        String exchangeName = "exchange_topic";
        String exchangeType = "topic";
        String routingKey = "user.*";

        //声明一个交换机
        channel.exchangeDeclare(exchangeName, exchangeType, true, false, false, null);
        //声明一个队列
        channel.queueDeclare(queueName, true, false, false, null);
        //建立关系
        channel.queueBind(queueName, exchangeName, routingKey);

        //5,创建消费者//
        QueueingConsumer queueingConsumer = new QueueingConsumer(channel);

        //6,设置channel
        channel.basicConsume(queueName, true, queueingConsumer);

        //7,获取消息
        while (true){
            QueueingConsumer.Delivery delivery = queueingConsumer.nextDelivery();
            String msg = new String(delivery.getBody());
            System.out.println(msg);
        }
    }
}

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
 * 生产者
 */
public class producer {

    public static void main(String[] args) throws IOException, TimeoutException {
        //创建工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("localhost");
        connectionFactory.setPort(5672);
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");
        //获取连接
        Connection connection = connectionFactory.newConnection();
        //通过connection创建一个channel
        Channel channel = connection.createChannel();

        String exchangeName = "exchange001";
        String routingKey = "routingKey0011";

        //发布消息
        for(int i = 0; i < 5; i++){
            String msg = "hello rabbitmq " + i;
            //1.exchange  2.routing key
            //默认交换器隐式绑定到每个队列,其路由键等于队列名. 如果没有队列名,则会被删除
            channel.basicPublish(exchangeName, routingKey, null, msg.getBytes());
        }
        channel.close();
        connection.close();

    }
}


Fanout Exchange

介绍

Fanout Exchange: 不处理路由键,只需要简单的将队列绑定到交换机上。发送到交换机上都会转发到与该交换机绑定的所有队列上。Fanout 交换机发消息是最快的。

在这里插入图片描述
     

代码实现
package com.example.rabbitmq.fanout;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.QueueingConsumer;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * 消费者类
 */
public class ConsumerFanout {

    public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
        //1,创建工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("localhost");
        connectionFactory.setPort(5672);
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");
        //2,获取连接
        Connection connection = connectionFactory.newConnection();
        //3,通过connection创建一个channel
        Channel channel = connection.createChannel();
        //4,exchange, routingkey, queue, 并将queue和交换机绑定
        String queueName = "fanout001";
        String queueName2 = "fanout002";
        //设置交换机
        String exchangeName = "exchange_fanout";
        String exchangeType = "fanout";
        String routingKey = "";

        //声明一个交换机
        channel.exchangeDeclare(exchangeName, exchangeType, true, false, false, null);
        //声明一个队列
        channel.queueDeclare(queueName, true, false, false, null);
        channel.queueDeclare(queueName2, true, false, false, null);
        //建立关系
        channel.queueBind(queueName, exchangeName, routingKey);
        channel.queueBind(queueName2, exchangeName, routingKey);
        //5,创建消费者//
        QueueingConsumer queueingConsumer = new QueueingConsumer(channel);
        //6,设置channel
        channel.basicConsume(queueName, true, queueingConsumer);
        //7,获取消息
        while (true){
            QueueingConsumer.Delivery delivery = queueingConsumer.nextDelivery();
            String msg = new String(delivery.getBody());
            System.out.println(msg);
        }
    }
}

package com.example.rabbitmq.fanout;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * 生产者类
 */
public class producerFanout {

    public static void main(String[] args) throws IOException, TimeoutException {
        //创建工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("localhost");
        connectionFactory.setPort(5672);
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");
        //获取连接
        Connection connection = connectionFactory.newConnection();
        //通过connection创建一个channel
        Channel chennel = connection.createChannel();

        String exchangeName = "exchange_fanout";
        String routingKey = "";

        //发布消息
        for(int i = 0; i < 5; i++){
            String msg = "hello rabbitmq " + i;
            //1.exchange  2.routing key
            //默认交换器隐式绑定到每个队列,其路由键等于队列名. 如果没有队列名,则会被删除
            chennel.basicPublish(exchangeName, routingKey, null, msg.getBytes());
        }
        chennel.close();
        connection.close();

    }
}

Headers Exchange

介绍

通过消息头进行路由(不常用)。
关键参数,x-match: 为all表示要匹配所有的header, 如果为any则表示只要匹配其中的一个header即可

//绑定队列时配置一个header
Map<String, Object> headerOne = new HashMap<>();
headerOne.put("college", "computer science");
headerOne.put("class", "001");
headerOne.put("x-match", "all");    //关键参数,x-match: 为all表示要匹配所有的header, 如果为any则表示只要匹配其中的一个header即可
channel.queueBind(queueNameOne, exchangeName, routingKey, headerOne);

具体代码如下:

package com.example.rabbitmq.header;

import com.example.rabbitmq.consumer.MyConsumer;
import com.rabbitmq.client.*;

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

/**
 * 消费者
 */
public class ConsumerHeader {

    public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
        //1,创建工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("localhost");
        connectionFactory.setPort(5672);
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");
        //2,获取连接
        Connection connection = connectionFactory.newConnection();
        //3,通过connection创建一个channel
        Channel channel = connection.createChannel();
        //4,exchange, routingkey, queue, 并将queue和交换机绑定
        String queueNameOne = "header001";
        String queueNameTwo = "header002";
        //设置交换机
        String exchangeName = "exchange_headers";
        String exchangeType = "headers";
        String routingKey = "test.header";

        //声明一个交换机
        channel.exchangeDeclare(exchangeName, exchangeType, true, false, false, null);
        //声明两个个队列
        channel.queueDeclare(queueNameOne, true, false, false, null);
        channel.queueDeclare(queueNameTwo, true, false, false, null);

        //建立关系
        //headerOne, 绑定队列时使用该headers
        Map<String, Object> headerOne = new HashMap<>();
        headerOne.put("college", "computer science");
        headerOne.put("class", "001");
        headerOne.put("x-match", "all");    //x-match: 为all表示要匹配所有的header, 如果为any则表示只要匹配其中的一个header即可
        channel.queueBind(queueNameOne, exchangeName, routingKey, headerOne);

        //headerOne, 绑定队列时使用该headers
        Map<String, Object> headerTwo = new HashMap<>();
        headerTwo.put("college", "computer science");
        headerTwo.put("class", "001");
        headerTwo.put("x-match", "any");    //x-match: 为all表示要匹配所有的header, 如果为any则表示只要匹配其中的一个header即可
        channel.queueBind(queueNameTwo, exchangeName, routingKey, headerTwo);

        //5,创建消费者One, 监听queueNameOne
        channel.basicConsume(queueNameOne, true, new MyConsumerOne(channel));
        //创建消费者Two, 监听queueNameTwo
        channel.basicConsume(queueNameTwo, true, new MyConsumerTwo(channel));
    }

    static class MyConsumerOne extends DefaultConsumer {
        public MyConsumerOne(Channel channel) {
            super(channel);
        }

        @Override
        public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties basicProperties,  byte[] body){
            System.out.println("----- consumerOne message -----");
            System.out.println("body = " + new String(body));
            System.out.println("");
        }
    }

    static class MyConsumerTwo extends DefaultConsumer {
        public MyConsumerTwo(Channel channel) {
            super(channel);
        }

        @Override
        public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties basicProperties,  byte[] body){
            System.out.println("----- consumerTwo message -----");
            System.out.println("body = " + new String(body));
            System.out.println("");
        }
    }

}

package com.example.rabbitmq.header;

import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeoutException;

/**
 * 生产者
 */
public class producerHeader {

    public static void main(String[] args) throws IOException, TimeoutException {
        //创建工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("localhost");
        connectionFactory.setPort(5672);
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");
        //获取连接
        Connection connection = connectionFactory.newConnection();
        //通过connection创建一个channel
        Channel chennel = connection.createChannel();

        String exchangeName = "exchange_headers";
        String routingKey = "";

        //消息one, 发送到queue001
        String msg = "hello rabbitmq one ";
        //消息one的header
        Map<String, Object> headerOne = new HashMap<>();
        headerOne.put("college", "computer science");
        headerOne.put("class", "001");
        //配置消息的属性
        AMQP.BasicProperties properties = new AMQP.BasicProperties.Builder()
                .headers(headerOne)
                .build();
        chennel.basicPublish(exchangeName, routingKey, properties, msg.getBytes());

        //消息two, 发送到queue002
        String msgTwo = "hello rabbitmq two ";
        //消息one的header
        Map<String, Object> headerTwo = new HashMap<>();
        headerTwo.put("college", "computer science");
        //配置消息的属性
        AMQP.BasicProperties propertiesTwo = new AMQP.BasicProperties.Builder()
                .headers(headerTwo)
                .build();
        chennel.basicPublish(exchangeName, routingKey, propertiesTwo, msgTwo.getBytes());

        //关闭连接
        chennel.close();
        connection.close();
    }
}

– 生成的exchange如下:
     虽然配置了Routingkey 但是不生效
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值