RabbitMQ 是一个消息队列系统,其核心架构由以下几个关键组件组成:
以下是 RabbitMQ 核心逻辑的架构图(使用 Mermaid 语法表示):
在这个架构中:
为了让 RabbitMQ 的工作原理更易于理解,我们将其与演唱会场景进行类比:
在这个类比中:
下面是一个使用 Java 和 RabbitMQ 客户端库的 Demo,模拟演唱会信息发布的场景。我们将使用 Direct Exchange 类型,因为它允许根据 routing key 精确匹配队列。
concert_exchange
)。social_media_queue
)。"social_media"
。"social_media"
。localhost:5672
)。<dependency>
<groupId>com.rabbitmqgroupId>
<artifactId>amqp-clientartifactId>
<version>5.14.0version>
dependency>
生产者发送一条演唱会信息到交换机。
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
public class ConcertProducer {
public static void main(String[] args) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost"); // RabbitMQ 服务器地址
try (Connection connection = factory.newConnection();
Channel channel = connection.createChannel()) {
String exchangeName = "concert_exchange";
channel.exchangeDeclare(exchangeName, "direct"); // 声明 Direct Exchange
String queueName = "social_media_queue";
channel.queueDeclare(queueName, false, false, false, null); // 声明队列
String routingKey = "social_media";
channel.queueBind(queueName, exchangeName, routingKey); // 绑定队列和交换机
String message = "演唱会信息:2023年12月1日,北京,票价500元";
channel.basicPublish(exchangeName, routingKey, null, message.getBytes());
System.out.println("消息已发送: " + message);
}
}
}
消费者从队列中接收消息并打印。
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;
public class ConcertConsumer {
public static void main(String[] args) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost"); // RabbitMQ 服务器地址
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
String queueName = "social_media_queue";
channel.queueDeclare(queueName, false, false, false, null); // 声明队列
DeliverCallback deliverCallback = (consumerTag, delivery) -> {
String message = new String(delivery.getBody(), "UTF-8");
System.out.println("收到消息: " + message);
};
channel.basicConsume(queueName, true, deliverCallback, consumerTag -> {});
System.out.println("等待接收消息...");
}
}
ConcertConsumer.java
,等待接收消息。ConcertProducer.java
,发送消息。运行后,你会在消费者端看到类似以下输出:
等待接收消息...
收到消息: 演唱会信息:2023年12月1日,北京,票价500元
生产者端输出:
消息已发送: 演唱会信息:2023年12月1日,北京,票价500元
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
public class ConcertProducer {
public static void main(String[] args) throws Exception {
// 创建连接工厂,用于配置与 RabbitMQ 服务器的连接
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost"); // 设置 RabbitMQ 服务器地址,默认端口 5672
// 使用 try-with-resources 建立连接和通道,确保资源自动关闭
try (Connection connection = factory.newConnection(); // 创建与 RabbitMQ 的连接
Channel channel = connection.createChannel()) { // 创建通道,用于发送消息
// 声明交换机(Exchange),类型为 Direct,用于精确路由消息
String exchangeName = "concert_exchange";
channel.exchangeDeclare(exchangeName, "direct");
// 声明队列(Queue),用于存储消息
String queueName = "social_media_queue";
channel.queueDeclare(queueName, false, false, false, null);
// 参数说明:
// - queueName: 队列名称
// - durable: false 表示队列非持久化,重启后丢失
// - exclusive: false 表示队列不专属于某个连接
// - autoDelete: false 表示队列不自动删除
// - arguments: null 表示无额外参数
// 将队列绑定到交换机,指定 routing key
String routingKey = "social_media";
channel.queueBind(queueName, exchangeName, routingKey);
// 绑定确保消息根据 routing key 路由到指定队列
// 发送消息到交换机
String message = "演唱会信息:2023年12月1日,北京,票价500元";
channel.basicPublish(exchangeName, routingKey, null, message.getBytes());
// 参数说明:
// - exchangeName: 目标交换机
// - routingKey: 路由键,用于匹配绑定
// - props: null 表示无额外消息属性
// - body: 消息内容,转换为字节数组
System.out.println("消息已发送: " + message); // 打印确认消息已发送
}
}
}
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;
public class ConcertConsumer {
public static void main(String[] args) throws Exception {
// 创建连接工厂,用于配置与 RabbitMQ 服务器的连接
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost"); // 设置 RabbitMQ 服务器地址,默认端口 5672
// 建立连接和通道
Connection connection = factory.newConnection(); // 创建与 RabbitMQ 的连接
Channel channel = connection.createChannel(); // 创建通道,用于接收消息
// 声明队列(Queue),确保队列存在
String queueName = "social_media_queue";
channel.queueDeclare(queueName, false, false, false, null);
// 参数与生产者一致,确保队列配置相同
// 定义消息接收回调,处理接收到的消息
DeliverCallback deliverCallback = (consumerTag, delivery) -> {
String message = new String(delivery.getBody(), "UTF-8"); // 将消息字节转换为字符串
System.out.println("收到消息: " + message); // 打印接收到的消息
};
// 订阅队列,设置自动确认消息
channel.basicConsume(queueName, true, deliverCallback, consumerTag -> {});
// 参数说明:
// - queueName: 订阅的队列名称
// - autoAck: true 表示自动确认消息,收到后立即从队列移除
// - deliverCallback: 消息到达时的处理逻辑
// - cancelCallback: 消费者取消时的回调(此处为空实现)
System.out.println("等待接收消息..."); // 提示消费者已就绪
}
}
以下是生产者和消费者之间消息传递的逻辑图,RabbitMQ 的核心流程:
逻辑图说明:
"social_media"
。social_media_queue
)。为了让 RabbitMQ 的工作原理更直观,我们将其与演唱会场景进行类比:
类比流程:
通过注释后的代码、逻辑图和演唱会场景类比,我们详细展示了 RabbitMQ 的核心工作流程:
这个 Demo 不仅通过代码实现了消息传递,还借助逻辑图和类比帮助您更直观地理解 RabbitMQ 的机制。希望这对您掌握 RabbitMQ 有所帮助!