【Rabbit MQ】Rabbit MQ 的结构详解,传输机制!!!

🔥 博客主页🔥 :【 坊钰_CSDN博客

欢迎各位点赞👍 评论**✍收藏⭐**

1. Rabbit MQ 的传输模型

Rabbit MQ 的结构模型及工作流程如下

Rabbit MQ 简单来说就是一个生产者消费者模型,负责消息接受,储存,转发

1.1 生产者和消费者

  • Producer:生产者,Rabbit MQ 的客户端,负责向Rabbit MQ 发送消息
  • Consumer:消费者,Rabbit MQ 的客户端,负责从Rabbit MQ 接收消息
  • Broker:就是 Rabbit MQ ,负责接受和发送消息

1.2 连接和信道

  • Connection:连接,客户端和 Rabbit MQ 的一个 TCP 连接,负责传输客户端和服务器之间的各种信息
  • Channel:信道,Channel 是建立在 Connecton 连接上的一个抽象层,一个 TCP 连接可以有多个Channel,连接上的消息接受和发送都依靠与 Channel 来实现的

1.3 虚拟机

  • Virtual host :虚拟机,虚拟概念,相当于另一台主机,一个 Broker 上可以有多个虚拟机

1.4 队列

  • Queue:队列,为Rabbit MQ 的底层内部对象,用于存储消息

多个消费者可以消费同一个队列

1.5 交换机

  • Exchange:交换机,消息到达 Broker 的第一站,负责接受生产者的消息,并把消息路由到对应的 Queue 上,交换机是进行消息的路由,根据规则来决定路由到那个队列上

1.6 Rabbit MQ 的工作流程

  1. Producer 生产了一条消息,并与 Broker 建立了一个 Connection ,开启了一个 Channel
  2. Producer 声明一个 Exchange 路由消息,声明一个 Queue 存放消息
  3. 由 Exchange 把消息路由到对应的 Queue
  4. Consumer 与 Broker 建立一个 Connection ,开启一个 Channel
  5. Consumer 根据上方规则,取出消息,正常消费

2. AMQP 协议

AMQP 是一种高级消息队列协议,AMQP 定义一套确定的消息交换功能,包含交换机,队列等......,使生产者能够将消息发送到交换机,路由到队列,在由消费者从队列中取出消息

Rabbit MQ 就是遵守 AMQP 协议的,AMQP 的结构模型和Rabbit MQ 的结构模型是一样的

3. Rabbit MQ 代码实现

3.1 引入依赖

cpp 复制代码
<dependency>
 <groupId>com.rabbitmq</groupId>
 <artifactId>amqp-client</artifactId>
 <version>5.7.3</version>
</dependency>

3.2 生产者代码

3.2.1 创建连接

java 复制代码
//创建连接工厂
ConnectionFactory factory = new ConnectionFactory();
//设置参数
factory.setHost("47.97.84.56");
factory.setPort(5672);
factory.setVirtualHost("test");

factory.setUsername("study");
factory.setPassword("123456");

//建立连接
Connection connection = factory.newConnection();

3.2.2 创建信道

java 复制代码
//创建信道
Channel channel = connection.createChannel();

3.2.3 声明一个队列

java 复制代码
/*
queueDeclare(String queue, boolean durable, boolean exclusive,
boolean autoDelete, Map<String, Object> arguments)
queue: 队列名称
durable: 是否持久化,true->为持久化,持久化的数据会存盘,服务器重启,数据不会丢失
exclusive: 是否独占, 只能有⼀个消费者监听队列,当Connection关闭时, 是否删除队列
autoDelete: 是否自动删除,当没有Consumer时,自动删除
*/

//如果没有 ok1 队列,则会自动创建,如果有,则不创建
channel.queueDeclare("ok1",true,false,false,null);

3.2.4 发送信息

当信息到达Rabbit MQ后,会先进入交换机中,如不特殊声明,则使用内置交换机,内置交换机的名称为(""),路由到对应的队列

java 复制代码
/*
basicPublish(String exchange, String routingKey, AMQP.BasicProperties props, byte[] body)
exchange: 交换机名称,非特定情况下,内置交换机名称为 ""
routingKey: 路由名称,routingKey = 队列名称
props: 配置信息
body: 消息数据
*/
String msg = "Hello Rabbit MQ!";
//使用内置交换机,默认名称为 "",routingKey 和队列名称一致,才能路由到对应的队列中
channel.basicPublish("","ok1",null,msg.getBytes(StandardCharsets.UTF_8));
System.out.println(msg + "消息发送成功!");

3.2.5 释放资源

用完Rabbit MQ 后及时关闭资源是一个好习惯

java 复制代码
//关闭资源,必须先关闭信道,再关闭连接
channel.close();
connection.close();

3.3 消费者代码

前几步骤和上述一致,建立工厂,建立连接,声明信道和队列,消费消息时有差别

java 复制代码
//消费信息
/*
basicConsume(String queue, boolean autoAck, Consumer callback)
queue: 队列名称
autoAck: 是否⾃动确认, 消费者收到消息之后,⾃动和MQ确认
callback: 回调对象
*/
System.out.println("消费者启动...");
DefaultConsumer consumer = new DefaultConsumer(channel) {
    /*
    回调⽅法, 当收到消息后, 会⾃动执⾏该⽅法
    consumerTag: 标识
    envelope: 获取⼀些信息, 交换机, 路由key
    properties:配置信息
    body:数据
    */
    @Override
    public void handleDelivery(String consumerTag, Envelope envelope,
                               AMQP.BasicProperties properties, byte[] body) throws IOException {
        System.out.println("接收到消息 " + new String(body));
    }
};
channel.basicConsume("ok1",true,consumer);
//等待消费者消费
TimeUnit.SECONDS.sleep(5);

4. 生产者和消费者源码

4.1 生产者

java 复制代码
public class Producer {

    public static void main(String[] args) throws IOException, TimeoutException {
        //创建连接工厂
        ConnectionFactory factory = new ConnectionFactory();
        //设置参数
        factory.setHost("47.97.84.56");
        factory.setPort(5672);
        factory.setVirtualHost("test");
        factory.setUsername("study");
        factory.setPassword("123456");
        //建立连接
        Connection connection = factory.newConnection();

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

        /*
        queueDeclare(String queue, boolean durable, boolean exclusive,
        boolean autoDelete, Map<String, Object> arguments)
        queue: 队列名称
        durable: 是否持久化,true->为持久化,持久化的数据会存盘,服务器重启,数据不会丢失
        exclusive: 是否独占, 只能有⼀个消费者监听队列,当Connection关闭时, 是否删除队列
        autoDelete: 是否自动删除,当没有Consumer时,自动删除
        */

        //如果没有 ok1 队列,则会自动创建,如果有,则不创建
        channel.queueDeclare("ok1",true,false,false,null);

        /*
        basicPublish(String exchange, String routingKey, AMQP.BasicProperties props, byte[] body)
        exchange: 交换机名称,非特定情况下,内置交换机名称为 ""
        routingKey: 路由名称,routingKey = 队列名称
        props: 配置信息
        body: 消息数据
        */
        System.out.println("生产者启动...");
        String msg = "Hello Rabbit MQ!";
        //使用内置交换机,默认名称为 "",routingKey 和队列名称一致,才能路由到对应的队列中
        channel.basicPublish("","ok1",null,msg.getBytes(StandardCharsets.UTF_8));
        System.out.println(msg + "消息发送成功!");

        //关闭资源,必须先关闭信道,再关闭连接
        channel.close();
        connection.close();
    }

}

4.2 消费者

java 复制代码
public class Consumerr {

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

        //创建连接工厂
        ConnectionFactory factory = new ConnectionFactory();

        //设置参数
        factory.setHost("47.97.84.56");
        factory.setPort(5672);
        factory.setVirtualHost("test");
        factory.setUsername("study");
        factory.setPassword("123456");

        //建立连接
        Connection connection = factory.newConnection();

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

        //创建队列
        channel.queueDeclare("ok1",true,false,false,null);

        //消费信息
        /*
        basicConsume(String queue, boolean autoAck, Consumer callback)
        queue: 队列名称
        autoAck: 是否⾃动确认, 消费者收到消息之后,⾃动和MQ确认
        callback: 回调对象
        */
        System.out.println("消费者启动...");
        DefaultConsumer consumer = new DefaultConsumer(channel) {
            /*
            回调⽅法, 当收到消息后, 会⾃动执⾏该⽅法
            consumerTag: 标识
            envelope: 获取⼀些信息, 交换机, 路由key
            properties:配置信息
            body:数据
            */
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope,
                                       AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("接收到消息 " + new String(body));
            }
        };
        channel.basicConsume("ok1",true,consumer);
        //等待消费者消费
        TimeUnit.SECONDS.sleep(5);
        //7. 释放资源 消费者相当于是⼀个监听程序, 不需要关闭资源
        //顺序不可改变
        //channel.close();
        //connection.close();

    }

}

5. 小结

以上就是对Rabbit MQ 的结构详解,传输机制介绍,具体还需宝子们去实践,如果觉得该博客对你有用的话,希望一键三连,点个关注不迷路,谢谢支持

相关推荐
Psycho_MrZhang2 小时前
Claude高质量产出
java·服务器·网络
spencer_tseng5 小时前
Stream not available [SysDictDataMapper.xml]
xml·java
蒸蒸yyyyzwd9 小时前
cpp对象模型学习笔记1.1-2.8
java·笔记·学习
程序员徐师兄10 小时前
Windows JDK11 下载安装教程,适合新手
java·windows·jdk11 下载安装·jdk11 下载教程
RANCE_atttackkk10 小时前
[Java]实现使用邮箱找回密码的功能
java·开发语言·前端·spring boot·intellij-idea·idea
五岳11 小时前
DTS按业务场景批量迁移阿里云MySQL表实战(下):迁移管理平台设计与实现
java·应用·dts
zhougl99611 小时前
Java 所有关键字及规范分类
java·开发语言
Python 老手11 小时前
Python while 循环 极简核心讲解
java·python·算法
请叫我头头哥11 小时前
SpringBoot进阶教程(八十九)rabbitmq长链接及域名TTL,多机房切换配置重连能力
rabbitmq·springboot