RabbitMQ四种交换机以及在管理页面中创建交换机、队列和绑定关系,代码示例

3 篇文章 0 订阅
2 篇文章 0 订阅

RabbitMQ是目前应用非常广泛的一种消息队列之一,今天就来简单说一下RabbitMQ的四种交换机

以及在管理页面中创建交换机、队列、绑定关系

一、RabbitMQ中的几个关键字的概念

开始讲之前先来简单描述一下RabbitMQ中的几个关键的概念:

Broker:可以简单的理解为安装了RabbitMQ服务的这台机器就可以称为一个Broker

Exchange:交换机,消息经由它,通过路由键来判断并决定把消息投递给哪个队列,它类似于一个路由器的角色

Queue:队列,最终将消息投递到队列中,由消费端监听队列进行消费

Binding:绑定关系,需要给交换机绑定队列,绑定时需要给一个路由键

Routingkey:路由键,交换机和队列进行绑定时,需要指定路由键或通配符路由键。交换机根据路由 键来决定消息投递到哪个或哪些队列

二、mq运行流程

使用RabbitMQ前,首先需要根据业务来创建交换机和队列,创建完成后需要给交换机绑定队列(交换机和队列可以是多对多的关系),绑定队列时要指定具体的路由键或者通配符路由键

当生产者发送一条消息的时候,需要指定交换机和路由键,消息到达Broker后先转给刚才指定的交换机,交换机再根据路由键来决定把消息投递给与自己绑定的哪一个或哪一些队列,最后再由消费端来监听这些队列,消费处理对应的消息

有了整体的概念后,接着来讲RabbitMQ的四种交换机,然后在管理页面中创建交换机、队列并绑定关系

三、RabbitMQ的四种交换机

最新版本的RabbitMQ有四种交换机类型,分别是:Direct exchange、Fanout exchange、Topic exchange、Headers exchange
1、Direct exchange—直接类型交换机

要求消息带的路由键和绑定的路由键完全匹配,这是一个完整的匹配。

比如一个队列A绑定到该交换机上的路由键是“abc”,则只有指定的路由键是“abc”的消息才被投递给队列A,其他的不会投递给队列A

2、Fanout Exchange—扇出类型交换机

只需要简单的将队列绑定到该类型交换机上,该类型的交换机绑定队列时可以不指定路由键(指定了好像也不生效,自己测试过)

当消息发送给该交换机后,它会将消息投递给与该交换机绑定的所有队列

很像广播,每台子网内的机器都会获得一份消息,Fanout交换机转发消息是最快的

3、Topic Exchange—主题类型交换机

将路由键和某模式进行匹配。此时队列需要绑定某一个模式上。符号#匹配0个或多个单词,符号 *匹配一个单词。

4、Headers Exchanges

这种不常用,可以选择性忽略

4.在管理页面中创建交换机、队列、绑定关系

首先需要搭建好RabbitMQ的环境,可以参考使用Docker快速安装部署RabbitMQ

搭建好后,在浏览器输入IP地址+端口号15672,来到登录页面,输入默认账号:guest 密码:guest

1、创建交换机

首先点击Exchange菜单,然后在下边的Add a new exchange 里输入要新创建的交换机信息

输入名称,选择类型,选择类型的时候点开有4种类型,就是咱们上边讲到的那4种,最后点Add exchange,一个新的交换机就创建成功了

我把上边讲的3种常用类型的交换机都进行了创建
在这里插入图片描述

2、创建队列

点击Queues菜单,在下边的Add a new queue里输入要新创建的队列信息

在这里插入图片描述

3、创建绑定关系

在交换机列表点击对应的交换机,进入绑定页面

我给3个换机都绑定了对应的队列,如下图所示
在这里插入图片描述在这里插入图片描述

五、发送消息测试

发送消息来测试一下
1、测试给Direct类型交换机发送消息

在交换机列表进入对应的交换机

输入对应的路由键Routing key和消息内容,点击发送

测试一条路由键为China的消息,根据我们建立的绑定关系,应该只有China这个队列能收到这条消息

可以看到,确实只有China这个队列能收到这条消息

收到消息后,我们可以点击对应的队列进去,获取刚才发的消息

点击Get Message(s)后,可以就可以获取到刚才发的消息了

2、测试给Fanout类型交换机发送消息

和上边的流程一样,我们给Fanout类型交换机发送消息,根据建立的绑定关系,所有和Fanout类型交换机绑定的对应都应该收到消息

如上图,可以看到和预期的一样所有和Fanout类型交换机绑定的对应都应该收到消息
3、测试给Topic类型交换机发送消息

测试发送一条路由键为China.news的消息,根据我们建立的绑定关系和绑定关系中的通配符路由键判断

这条消息3个队列应该都可以收到

六、代码示例

1.生产者

package com.cloud.mq.test5;

import com.cloud.mq.utils.RabbitMqUtil;
import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;

import java.util.Scanner;

/**
 * @author liuYuHao
 * @create 2021/12/23 15:38
 */
public class Producer5 {

    //队列的名字
    private final static String EXCHANGE_NAME = "testExchange";

    //发送消息
    public static void main(String[] args) throws Exception {

        Channel channel = RabbitMqUtil.getChannel();

        /**
         * 声明交换机
         * 1.交换机名字
         * 2.交换机类型
         */
        channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.FANOUT);

        /**
         *发送一个消息
         *1.发送到哪个交换机,""表示不写
         *2.路由的 key 是哪个,扇出类型不用写
         *3.其他的参数信息 MessageProperties.PERSISTENT_TEXT_PLAIN,消息持久化
         *4.发送消息的消息体,消息的二进制
         */
        System.out.print("请输入发送消息内容");
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()){
            String sendMessage = scanner.next();
            channel.basicPublish(EXCHANGE_NAME,"", null,sendMessage.getBytes("UTF-8"));
            System.out.println("消息发送完毕" + sendMessage);
        }



    }
}

2.消费者1

package com.cloud.mq.test5;

import com.cloud.mq.utils.RabbitMqUtil;
import com.cloud.mq.utils.SleepUtil;
import com.rabbitmq.client.*;

import java.util.Scanner;

/**
 * ReceiveLogs02 把接收到的消息打印在控制台
 */
public class Consumer5a {
    //队列的名字
    private final static String EXCHANGE_NAME = "testExchange";

    //发送消息
    public static void main(String[] args) throws Exception {

        Channel channel = RabbitMqUtil.getChannel();

        /**
         * 声明交换机
         * 1.交换机名字
         * 2.交换机类型
         */
        channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.FANOUT);

        /**
         * 生成一个临时的队列 队列的名称是随机的
         * 当消费者断开和该队列的连接时 队列自动删除
         */
        String queueName = channel.queueDeclare().getQueue();

        /**
         * binding交换机和队列
         * 1.队列名字
         * 2.交换机名字
         * 3.routing_key,扇出类型,写了也不生效
         */
        channel.queueBind(queueName, EXCHANGE_NAME, "aaaaaaaaaa");

        System.out.println("Consumer5a等待接收消息,把接收到的消息打印在屏幕......");
        DeliverCallback deliverCallback = (consumerTag, delivery) -> {
            System.out.println("Consumer5a控制台打印接收到的消息" + new String(delivery.getBody()));
        };
        channel.basicConsume(queueName, true, deliverCallback, consumerTag -> { });


    }
}

消费者2

package com.cloud.mq.test5;

import com.cloud.mq.utils.RabbitMqUtil;
import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DeliverCallback;

import java.util.Scanner;

/**
 * ReceiveLogs02 将接收到的消息存储在磁盘
 */
public class Consumer5b {
    //队列的名字
    private final static String EXCHANGE_NAME = "testExchange";

    //发送消息
    public static void main(String[] args) throws Exception {

        Channel channel = RabbitMqUtil.getChannel();

        /**
         * 声明交换机
         * 1.交换机名字
         * 2.交换机类型
         */
        channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.FANOUT);

        /**
         * 生成一个临时的队列 队列的名称是随机的
         * 当消费者断开和该队列的连接时 队列自动删除
         */
        String queueName = channel.queueDeclare().getQueue();

        /**
         * binding交换机和队列
         * 1.队列名字
         * 2.交换机名字
         * 3.routing_key
         */
        channel.queueBind(queueName,EXCHANGE_NAME,"");

        System.out.println("Consumer5b等待接收消息,把接收到的消息打印在屏幕......");
        DeliverCallback deliverCallback = (consumerTag,delivery) -> {
            System.out.println("Consumer5b控制台打印接收到的消息" + new String(delivery.getBody()));
        };

        channel.basicConsume(queueName, true, deliverCallback, consumerTag -> { });
    }
}

4.工具类

package com.cloud.mq.utils;

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

/**
 * 此类为连接工厂创建信道的工具类
 */
public class RabbitMqUtil {

    //得到一个连接的channeer
    public static Channel getChannel() throws Exception {

        //创建一个连接工厂
        ConnectionFactory factory = new ConnectionFactory();
        /**
         *写自己的服务器名字,账号,密码
         */
        factory.setHost("192.168.6.133");
        factory.setUsername("admin");
        factory.setPassword("123");

        //创建连接
        Connection connection = factory.newConnection();
        //获取信道
        Channel channel = connection.createChannel();
        return channel;

    }
}

*喏,手打不易,大家动动小手分享转发点赞评论啥的~~~~*
在这里插入图片描述

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
RabbitMQ ,新建交换机队列绑定它们之间的关系非常简单。 首先,需要连接到 RabbitMQ 服务器,并创建一个通道: ```python import pika # 连接到 RabbitMQ 服务器 connection = pika.BlockingConnection(pika.ConnectionParameters('localhost')) channel = connection.channel() ``` 然后,可以使用 `channel.exchange_declare()` 方法创建一个新的交换机。该方法有四个参数: - `exchange`: 交换机名称 - `exchange_type`: 交换机类型,可以是 `direct`、`fanout`、`topic` 或 `headers` - `durable`: 是否持久化,如果为 `True`,则交换机会在 RabbitMQ 服务器重启后仍然存在 - `auto_delete`: 是否自动删除,如果为 `True`,则交换机在不再被使用时会自动删除 例如,创建一个名为 `my_exchange` 的 `fanout` 类型的交换机,可以使用以下代码: ```python channel.exchange_declare(exchange='my_exchange', exchange_type='fanout', durable=True, auto_delete=False) ``` 接下来,可以使用 `channel.queue_declare()` 方法创建一个新的队列。该方法有三个参数: - `queue`: 队列名称,如果未指定,则会自动生成一个随机名称的队列 - `durable`: 是否持久化,如果为 `True`,则队列会在 RabbitMQ 服务器重启后仍然存在 - `auto_delete`: 是否自动删除,如果为 `True`,则队列在不再被使用时会自动删除 例如,创建一个名为 `my_queue` 的队列,可以使用以下代码: ```python channel.queue_declare(queue='my_queue', durable=True, auto_delete=False) ``` 最后,可以使用 `channel.queue_bind()` 方法将交换机队列绑定在一起。该方法有三个参数: - `queue`: 队列名称 - `exchange`: 交换机名称 - `routing_key`: 路由键,用于将消息发送到特定的队列。对于 `fanout` 类型的交换机,该参数可以为空字符串。 例如,将名为 `my_queue` 的队列绑定到名为 `my_exchange` 的交换机上,可以使用以下代码: ```python channel.queue_bind(queue='my_queue', exchange='my_exchange', routing_key='') ``` 以上就是 RabbitMQ 新建交换机队列绑定它们之间关系的基本流程。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值