RabbitMQ---开篇

1.什么是MQ?

MQ是Message Queue的缩写,从字面意思来说就是一个消息队列,也就是一个用来存储消息的队列,消息可以非常简单,比如只包含文本字符串,JSON格式的数据,也可以很复杂,比如内嵌对象

2.MQ的作用

1.异步解耦,我们在根据实际业务去写代码时,可能这个业务中的有些操作是非常耗时的,但是这些操作不追求实时的返回结果,这时候就可以通过MQ异步的去实现这些操作。比如用户注册时,如果用户注册成功,此时就需要向用户发送短信或者邮件,此时这些发送短信和邮件的操作就可以通过MQ异步的处理,此时就不用让用户等待短信或者邮件发送成功后,用户才会变成注册成功的状态

2.流量削峰,为了应对一些访问量突增的情况,为了保证应用能够正常的运行,就需要对这种访问量突增的情况进行防范。但是这种访问量突增的情况并不是很常见的,可能就只会在一些类似于双十一的日子出现,此时如果按照这种流量突增的峰值去购入其他服务器,但是这样就会导致这些服务器在未来有一部分就会处于空闲状态,这个是很没有性价比的。此时就可以考虑MQ中间件,这种性价比高的方式来应对这种流量突增的情况,可以MQ来控制流量,先将请求放到MQ中,然后系统根据自己的能力去逐步得去处理这些请求

3.消息分发,假设此时有多个系统需要对同一份的数据的变化做出反应,常见的做法可能就是轮询数据库,比如订单系统、积分系统等系统都需要知道"支付成功",这些系统就可能会定时去查询数据库,看看有没有新的支付记录产生,但是这种操作是定时的,就会导致数据的实时性差,且有可能给数据造成压力。此时MQ就派上用场了,举个例子,假设用户支付成功了,此时就会生成一条支付成功的记录,此时就可以将这条记录以消息的形式发送给MQ并存储在MQ中,此时就可以让那些需要知道支付记录的系统自己去MQ订阅和消费对应的消息即可

4.延迟通知,延迟通知就是当希望某个消息不希望立即被消费者处理,而是需要等待一段时间后再被消费,从而实现延迟执行或者延迟通知的效果,比如在订单超时未支付自动取消,此时用户下单后,发送一条延迟消息到MQ中,30分钟后再被消费,消费时检查订单是否已支付,如果没有则取消订单

3.RabbitMQ

RabbitMQ是采用Erlang语言实现的AMQP的消息中间件,为了在分布式系统中存储和转发消息而设计的

4.RabbitMQ的核心概念

RabbitMQ是一个消息中间件,也是一个生产者消费者模型,它负责接收,存储并转发消息,下图是RabbitMQ的一个抽象图

下图是RabbitMQ的具体工作流程图

4.1 Producer

Producer就是生产者,是RabbitMQ的客户端,向RabbitMQ发送消息,在实际的业务中生产者发送的消息通常是一个带有业务逻辑结构的数据,比如JSON字符串,消息也可以带哟一定的标签,RabbitMQ会根据标签进行路由(就是根据标签将消息发生给对应的队列中)

4.2 Consumer

Consumer就是消费者,也是RabbitMQ的客户端,从RabbitMQ中获取消息,当消费者连接到RabbitMQ的服务器,就可以消费队列中的消息了,当对应的消息被消费后,该消息的标签就会被丢弃.

4.3 Broker

Broker可以看做是RabbitMQ的服务器,Broker有多个Virtual Host(虚拟机),这个虚拟机不是我们平常所说的虚拟机,可以看做类似于MySQL中的库的概念,一个虚拟机中包含多个Exchange(交换机)和Queue(队列)

4.4 Virtual Host

Virtual Host就是虚拟主机,它为消息队列提供了一种逻辑上的隔离机制,一个Broker中可以分割为多个Virtual Host,当有多个用户共同使用一个RabbitMQ Broker时,此时不同用户就可以在各自的Virtual Host中创建各自的Exchange和Queue来使用

4.5 Queue

Queue是RabbitMQ的内置队列,就是队列,不过是一个用来存储消息的队列

4.6 Exchange

Exchange就是交换机,当消费者发送消息给Broker时,首先Broker中对应的Virtual Host里的Exchange会先接收到消息,并根据消息的标签将消息转发给一个或者多个队列(Queue)

4.7 Connection

Connection就是建立连接,如果生产者想要向RabbitMQ发送消息或者消费者想要消费RabbitMQ里面的消息,必须要要和RabbitMQ的服务器建立连接,这个连接就是Connection,一次Connection就是一次TCP连接

4.8 Channel

Channel就是通道,为了解决多个生产者同时发送消息或者多个消费者同时去消费消息而频繁建立连接,消费资源,每个Connection中可以有多个Channel,消息的发送和消费都是基于Channel的,这样就可以将多个消息的读写复用到一个TCP连接上,就可以减少建立和关闭连接带来的开销.

5.RabbitMQ快速上手---生产者代码

java 复制代码
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

public class Producer {

    // 队列名称(消费者也要用同一个)
    private static final String QUEUE_NAME = "hello_queue";

    public static void main(String[] args) throws Exception {

        // 1️⃣ 创建连接工厂(类似数据库连接池的配置)
        ConnectionFactory factory = new ConnectionFactory();

        // 2️⃣ 设置 RabbitMQ 服务器地址
        factory.setHost("localhost");   // 本地运行
        factory.setPort(5672);           // RabbitMQ 默认端口
        factory.setUsername("guest");    // 默认用户名
        factory.setPassword("guest");    // 默认密码

        // 3️⃣ 建立 TCP 连接(真实网络连接)
        Connection connection = factory.newConnection();

        // 4️⃣ 创建一个通信通道(Channel)
        // ⚠️ RabbitMQ 几乎所有操作都在 Channel 上进行
        Channel channel = connection.createChannel();

        // 5️⃣ 声明一个队列(如果不存在就创建)
        /*
        参数说明:
        queue       -- 队列名
        durable     -- 是否持久化(false=重启后消失)
        exclusive   -- 是否排他(仅当前连接可用)
        autoDelete  -- 是否自动删除(没有消费者时删除)
        arguments   -- 额外参数(一般 null)
         */
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);

        // 6️⃣ 要发送的消息
        String message = "Hello RabbitMQ!";

        // 7️⃣ 发送消息
        /*
        exchange    -- 交换机("" 表示默认交换机)
        routingKey  -- 路由键(这里直接用队列名)
        props       -- 消息属性(比如持久化、优先级)
        body        -- 消息内容(必须是字节数组)
         */
        channel.basicPublish(
                "",                 // 默认交换机
                QUEUE_NAME,         // 队列名
                null,               // 无额外属性
                message.getBytes()  // 消息转成字节
        );

        // 8️⃣ 打印日志
        System.out.println(" [x] Sent '" + message + "'");

        // 9️⃣ 关闭资源(生产环境建议用 try-with-resources)
        channel.close();
        connection.close();
    }
}

6.RabbitMQ快速上手---消费者代码

java 复制代码
import com.rabbitmq.client.*;

import java.io.IOException;

public class Consumer {

    // 队列名必须和生产者一致
    private static final String QUEUE_NAME = "hello_queue";

    public static void main(String[] args) throws Exception {

        // 1️⃣ 创建连接工厂
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("localhost");
        factory.setPort(5672);
        factory.setUsername("guest");
        factory.setPassword("guest");

        // 2️⃣ 创建连接
        Connection connection = factory.newConnection();

        // 3️⃣ 创建通道
        Channel channel = connection.createChannel();

        // 4️⃣ 声明队列(防止队列不存在)
        channel.queueDeclare(QUEUE_NAME, false, false, false, null);

        System.out.println(" [*] Waiting for messages...");

        // 5️⃣ 创建 DeliverCallback(不用 lambda)
        DeliverCallback deliverCallback = new DeliverCallback() {
            @Override
            public void handle(String consumerTag, Delivery delivery) throws IOException {
                // 把消息转成字符串
                String message = new String(delivery.getBody(), "UTF-8");
                System.out.println(" [x] Received: " + message);
            }
        };

        // 6️⃣ 创建 CancelCallback(不用 lambda)
        CancelCallback cancelCallback = new CancelCallback() {
            @Override
            public void handle(String consumerTag) {
                System.out.println(" [x] Consumer cancelled: " + consumerTag);
            }
        };

        // 7️⃣ 开始消费消息
        channel.basicConsume(
                QUEUE_NAME,     // 队列名
                true,           // 自动确认
                deliverCallback,
                cancelCallback
        );
    }
}
相关推荐
小旭95273 小时前
RabbitMQ 核心详解
分布式·rabbitmq
我只想困告1 天前
day01-RabbitMQ_2026-05-13
分布式·rabbitmq
cheems95271 天前
[RabbitMQ] RabbitMQ 工作流程全解析
分布式·rabbitmq
我只想困告1 天前
day02-RabbitMQ 2026-05-14
java·spring·rabbitmq
heimeiyingwang1 天前
【架构实战】RabbitMQ实战:企业级消息可靠传递
架构·rabbitmq·ruby
zkkkkkkkkkkkkk3 天前
python使用celery实现异步任务
redis·python·rabbitmq·rocketmq
小英雄大肚腩丶3 天前
RabbitMQ消息队列
java·数据结构·spring boot·分布式·rabbitmq·java-rabbitmq
StackNoOverflow3 天前
RabbitMQ 从入门到实战:详解安装、五种消息模型及持久化
分布式·rabbitmq
老码观察3 天前
数环通消息中间件选型实录:RocketMQ vs Kafka vs RabbitMQ,我们为什么选了RocketMQ
kafka·rabbitmq·rocketmq