RabbitMQ交换机

本文介绍了RabbitMQ中交换机的基本属性,包括Name、Type、Durability等,并详细讲解了三种类型的交换机:直接交换机(direct exchange)、主题交换机(TopicExchange)和扇形交换机(fanout exchange)。直接交换机依赖于route key和queue名称的匹配,主题交换机支持通配符路由匹配,而扇形交换机则以最快的速度将消息分发到所有绑定的队列。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、交换机的属性

Name:交换机的名称
Type:交换机的类型,direct,topic,fanout,headers
Durability:是否需要持久化
autodelete:假如没有队列绑定到该交换机,那么该交换机会自动删除
Internal:当前交换机是否用户rabbitmq内部使用不常用,默认为false
Argurements:扩展参数,用户扩展AMQP 定制化协议

二、交换机的类型

2.1 直接交换机 direct exchange

所有发送到direct exchange的消息都会被投递到route key名称和queue名称相同的queue上
在这里插入图片描述
举个栗子

public class DirectExchangeProductor {

    public static void main(String[] args) throws IOException, TimeoutException {

        //创建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("10.101.102.167");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("test_vm1");
        connectionFactory.setUsername("admin");
        connectionFactory.setPassword("admin");

        //创建连接
        Connection connection = connectionFactory.newConnection();

        //创建channel
        Channel channel = connection.createChannel();

        //定义交换机名称
        String exchangeName = "testDirect1";

        //定义routingKey
        String routingKey = "testExchange1.queue1";

        //消息体内容
        String messageBody = "hello world ";
        channel.basicPublish(exchangeName,routingKey,null,messageBody.getBytes());

    }
}

public class DirectExchangeConsumer {

    public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {

        //创建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("10.101.102.167");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("test_vm1");
        connectionFactory.setUsername("admin");
        connectionFactory.setPassword("admin");

        //创建连接
        Connection connection = connectionFactory.newConnection();

        //创建channel
        Channel channel = connection.createChannel();

        String exchangeName = "testDirect1";
        String exchangeType = "direct";
        String queueName = "testQueue1";
        String routingKey = "testExchange1.queue1";
        /**
         * 声明一个交换机
         * exchange:交换机的名称
         * type:交换机的类型 常见的有direct,fanout,topic等
         * durable:设置是否持久化。durable设置为true时表示持久化,反之非持久化.持久化可以将交换器存入磁盘,在服务器重启的时候不会丢失相关信息
         * autodelete:设置是否自动删除。autoDelete设置为true时,则表示自动删除。自动删除的前提是至少有一个队列或者交换器与这个交换器绑定,之后,所有与这个交换器绑定的队列或者交换器都与此解绑。
         * 不能错误的理解—当与此交换器连接的客户端都断开连接时,RabbitMq会自动删除本交换器
         * arguments:其它一些结构化的参数,比如:alternate-exchange
         */
        channel.exchangeDeclare(exchangeName,exchangeType,true,false,null);

        /**
         * 声明一个队列
         * durable:表示rabbitmq关闭删除队列
         * autodelete:表示没有程序和队列建立连接 那么就会自动删除队列
         *
         */
        channel.queueDeclare(queueName,true,false,false,null);

        /**
         * 队列和交换机绑定
         */
        channel.queueBind(queueName,exchangeName,routingKey);

        /**
         * 创建一个消费者
         */
        QueueingConsumer queueingConsumer = new QueueingConsumer(channel);

        /**
         * 开始消费
         */
        channel.basicConsume(queueName,true,queueingConsumer);

        while (true) {
            QueueingConsumer.Delivery delivery = queueingConsumer.nextDelivery();
            String reciverMessage = new String(delivery.getBody());
            System.out.println("消费消息:-----"+reciverMessage);
        }

    }
}

2.2 主题交换机 TopicExchange

就是在队列上绑到交换机上的路由key 可以是通过通配符来匹配的。
通配符的规则是:
log.# :可以匹配一个单词,也可以匹配多个单词。比如log.#可以匹配log.a、log.b、log.a.b
log.* : 可以匹配一个单词。比如 log.* 可以匹配log.a但是不可以匹配log.a.b
在这里插入图片描述
举个栗子

public class TopicExchangeProductor {

    public static void main(String[] args) throws IOException, TimeoutException {

        //创建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("10.101.102.167");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("test_vm1");
        connectionFactory.setUsername("admin");
        connectionFactory.setPassword("admin");

        //创建连接
        Connection connection = connectionFactory.newConnection();

        //创建channel
        Channel channel = connection.createChannel();

        //发送消息
        String exchangeName = "testDirect1";

        String routingKey1 = "testExchange1.queue1.queue1";
        String routingKey2 = "testExchange1.queue2";
        String routingKey3 = "testExchange1.queue3";

        channel.basicPublish(exchangeName,routingKey1,null,"我是第一条消息".getBytes());
        channel.basicPublish(exchangeName,routingKey2,null,"我是第二条消息".getBytes());
        channel.basicPublish(exchangeName,routingKey3,null,"我是第三条消息".getBytes());
    }
}
public class TopicExchangeConsumer {

    public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
        //创建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("10.101.102.167");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("test_vm1");
        connectionFactory.setUsername("admin");
        connectionFactory.setPassword("admin");

        //创建连接
        Connection connection = connectionFactory.newConnection();

        //创建channel
        Channel channel = connection.createChannel();

        //声明交换机
        String exchangeName = "testDirect1";
        String exchangeType = "topic";
        channel.exchangeDeclare(exchangeName,exchangeType,true,true,null);

        //声明队列
        String quequName = "testQueue1";
        channel.queueDeclare(quequName,true,false,false,null);

        //声明绑定关系
        String bingdingStr = "testExchange1.*";
        channel.queueBind(quequName,exchangeName,bingdingStr);

        //声明一个消费者
        QueueingConsumer queueingConsumer = new QueueingConsumer(channel);

        //开始消费
        /**
         * 开始消费
         */
        channel.basicConsume(quequName,true,queueingConsumer);

        while (true) {
            QueueingConsumer.Delivery delivery = queueingConsumer.nextDelivery();
            System.out.println("接受到消息:"+new String(delivery.getBody()));
        }
    }
}

执行结果
在这里插入图片描述

2.3 扇形交换机(fanout exchange)

就是消息通过从交换机到队列上不会通过路由key ,所以该模式的速度是最快的,只要和交换机绑定,那么消息就会
被分发到与之绑定的队列上

举个栗子

public class FanoutExchangeProductor {

    public static void main(String[] args) throws IOException, TimeoutException {
        //创建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("10.101.102.167");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("test_vm1");
        connectionFactory.setUsername("admin");
        connectionFactory.setPassword("admin");

        //创建连接
        Connection connection = connectionFactory.newConnection();

        //创建channel
        Channel channel = connection.createChannel();

        //定义交换机名称
        String exchangeName = "testDirect2";

        //定义routingKey
        String routingKey = "";

        //消息体内容
        String messageBody = "hello world ";
        channel.basicPublish(exchangeName,"123",null,"我是第一条消息".getBytes());
        channel.basicPublish(exchangeName,"456",null,"我是第二条消息".getBytes());
        channel.basicPublish(exchangeName,"789",null,"我是第三条消息".getBytes());
    }
}

public class FanoutExchangeConsumer {

    public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
        //创建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("10.101.102.167");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("test_vm1");
        connectionFactory.setUsername("admin");
        connectionFactory.setPassword("admin");

        //创建连接
        Connection connection = connectionFactory.newConnection();

        //创建channel
        Channel channel = connection.createChannel();

        //声明交换机
        String exchangeName = "testDirect2";
        String exchangeType = "fanout";
        channel.exchangeDeclare(exchangeName,exchangeType,true,true,null);

        //声明队列
        String quequName = "testQueue2";
        channel.queueDeclare(quequName,true,false,false,null);

        //声明绑定关系
        String bingdingStr = "不需要绑定关系";
        channel.queueBind(quequName,exchangeName,bingdingStr);

        //声明一个消费者
        QueueingConsumer queueingConsumer = new QueueingConsumer(channel);

        //开始消费
        channel.basicConsume(quequName,true,queueingConsumer);

        while (true) {
            QueueingConsumer.Delivery delivery = queueingConsumer.nextDelivery();
            System.out.println("接受到消息:"+new String(delivery.getBody()));
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值