一、什么是 MQ
MQ(Message Queue,消息队列),也叫消息中间件,是用于分布式系统之间通信的核心组件。它的核心作用是实现系统间的异步通信,解耦上下游系统,同时具备削峰填谷的能力,保障高并发场景下系统的稳定性。
二、主流 MQ 对比与选型
在分布式架构中,常见的消息中间件有 RabbitMQ、ActiveMQ、RocketMQ、Kafka,不同组件的特性差异显著,选型需结合业务场景:
| 特性 | RabbitMQ | ActiveMQ | RocketMQ | Kafka |
|---|---|---|---|---|
| 开发团队 / 社区 | Rabbit | Apache | 阿里 | Apache |
| 开发语言 | Erlang | Java | Java | Scala&Java |
| 通信协议 | AMQP | OpenWire、AUTO、Stomp、MQTT | 自定义 | 自定义 |
| 单机吞吐量 | 万级 | 万级(性能最差) | 十万级 | 十万级 |
| 消息延迟 | 微妙级 | 毫秒级 | 毫秒级 | 毫秒以内 |
| 核心特性 | 高并发、低延时、社区活跃 | 老牌产品、文档丰富 | 功能完备、扩展性强 | 专为大数据场景设计,仅支持核心 MQ 功能 |
选型建议
- 中小型企业:优先选择 RabbitMQ。Erlang 语言天生具备高并发特性,RabbitMQ 社区活跃,问题解决成本低;且功能完备,能满足中小型系统的绝大多数场景需求。
- 大型企业 / 互联网公司:根据场景在 RocketMQ 和 Kafka 中选择。RocketMQ 适合业务级消息场景,支持定制化开发;Kafka 适合日志采集、大数据流式处理等超高吞吐场景。
三、RabbitMQ 核心概念
3.1 基础定义
RabbitMQ 是基于 AMQP(高级消息队列协议)开发的消息中间件,2007 年由 Rabbit 技术公司发布,采用 Erlang 语言开发,天然适配高并发场景。
3.2 AMQP 协议核心组成
AMQP 协议定义了消息传递的规范,核心要素包括:
- 生产者(Producer):发送消息的应用程序。
- 消费者(Consumer):接收并处理消息的应用程序。
- 交换机(Exchange):接收生产者发送的消息,根据路由规则将消息路由到对应的队列。
- 队列(Queue):存储消息的缓冲区,消息只有被消费后才会从队列移除。
- 绑定(Binding):交换机与队列之间的关联关系,定义路由规则。
- 连接(Connection):生产者 / 消费者与 RabbitMQ 之间的 TCP 连接。
- 通道(Channel):建立在 Connection 之上的轻量级连接,消息的生产 / 消费均通过通道完成(避免频繁创建 TCP 连接)。
3.3 RabbitMQ 核心价值
3.3.1 解耦
传统架构中,系统 A 直接调用系统 B、C 的接口,新增系统 D 时需修改 A 的代码;基于 RabbitMQ,系统 A 只需将消息发送到队列,其他系统自行订阅队列,无需修改 A 的代码,彻底解耦系统间依赖。
3.3.2 异步
传统同步调用中,非核心业务(如短信通知、日志记录)会阻塞主流程,延长响应时间;基于 RabbitMQ,主流程只需发送消息,非核心业务异步消费,大幅提升接口响应速度。
3.3.3 削峰
高并发场景下,大量请求直接冲击数据库易导致连接耗尽、服务崩溃;RabbitMQ 可缓存请求,消费者按照数据库的处理能力匀速拉取消息,避免系统被峰值流量压垮。
四、RabbitMQ 安装(CentOS)
4.1 安装依赖(Erlang)
RabbitMQ 基于 Erlang 开发,需先安装 Erlang 环境:
bash:
# 上传Erlang安装包后执行以下命令
rpm -ivh esl-erlang-17.3-1.x86_64.rpm --force --nodeps
rpm -ivh esl-erlang_17.3-1~centos~6_amd64.rpm --force --nodeps
rpm -ivh esl-erlang-compat-R14B-1.el6.noarch.rpm --force --nodeps
4.2 安装 RabbitMQ
bash:
# 上传RabbitMQ安装包后执行
rpm -ivh rabbitmq-server-3.4.1-1.noarch.rpm
# 启动/停止/重启服务
service rabbitmq-server start
service rabbitmq-server stop
service rabbitmq-server restart
# 查看服务状态
service rabbitmq-server status
# 设置开机自启
chkconfig rabbitmq-server on
4.3 配置 RabbitMQ
4.3.1 开放端口
bash:
# 开放15672(管理界面)、5672(客户端连接)端口
/sbin/iptables -I INPUT -p tcp --dport 15672 -j ACCEPT
/sbin/iptables -I INPUT -p tcp --dport 5672 -j ACCEPT
/etc/rc.d/init.d/iptables save
4.3.2 开启 Web 管理界面
bash:
rabbitmq-plugins enable rabbitmq_management
service rabbitmq-server restart
4.3.3 创建管理员账户
bash:
# 创建账号(用户名:admin,密码:1111)
rabbitmqctl add_user admin 1111
# 设置用户角色为超级管理员
rabbitmqctl set_user_tags admin administrator
# 设置用户权限(允许访问所有资源)
rabbitmqctl set_permissions -p "/" admin ".*" ".*" ".*"
# 查看用户列表
rabbitmqctl list_users
4.3.4 访问管理界面
浏览器访问 http://服务器IP:15672,使用创建的 admin 账号登录,即可进入 RabbitMQ 管理控制台。
4.4 管理控制台核心功能
- Connections:查看生产者 / 消费者与 RabbitMQ 的连接状态。
- Channels:查看所有通道信息,消息的生产 / 消费均通过通道完成。
- Exchanges:管理交换机,配置路由规则。
- Queues:管理消息队列,查看队列消息数、消费状态等。
- Users:管理用户,配置角色和权限。
- Virtual Hosts:虚拟主机,类似数据库的 "库",用于隔离不同业务的资源。
五、RabbitMQ 工程搭建(SpringBoot)
5.1 创建 Maven 工程
xml:
XML
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.2.RELEASE</version>
</parent>
<groupId>com.powershop</groupId>
<artifactId>springboot_rabbitmq</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!-- RabbitMQ核心依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
</dependencies>
</project>
5.2 封装 RabbitMQ 连接工具类
java:
java
package com.powershop.util;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
public class ConnectionUtil {
/**
* 获取RabbitMQ连接
*/
public static Connection getConnection() throws Exception {
// 1.创建连接工厂
ConnectionFactory factory = new ConnectionFactory();
// 2.配置连接信息
factory.setHost("服务器IP"); // RabbitMQ服务器地址
factory.setPort(5672); // 客户端连接端口
factory.setUsername("admin"); // 用户名
factory.setPassword("1111"); // 密码
factory.setVirtualHost("/"); // 虚拟主机
// 3.创建连接
return factory.newConnection();
}
}
六、RabbitMQ 五种核心消息模型
RabbitMQ 提供 5 种核心消息模型(排除 RPC 模型),其中 3-5 属于订阅模型,仅路由方式不同。
6.1 简单模型(Simple)
核心原理
生产者将消息直接发送到队列,消费者监听队列并获取消息;一个队列可被多个消费者监听,但一条消息仅能被一个消费者消费。
6.1.1 生产者(发送消息)
java:
java
package com.powershop.simple;
import com.powershop.util.ConnectionUtil;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
public class Send {
// 队列名称
private final static String QUEUE_NAME = "simple_queue";
public static void main(String[] argv) throws Exception {
// 1.获取连接
Connection connection = ConnectionUtil.getConnection();
// 2.创建通道
Channel channel = connection.createChannel();
// 3.声明队列(幂等性:不存在则创建,存在则忽略)
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
// 4.发送消息
String message = "Hello RabbitMQ!";
channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
System.out.println("生产者发送消息:" + message);
// 5.关闭资源
channel.close();
connection.close();
}
}
6.1.2 消费者(接收消息)
java:
java
package com.powershop.simple;
import com.powershop.util.ConnectionUtil;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import com.rabbitmq.client.AMQP.BasicProperties;
import java.io.IOException;
public class Recv {
private final static String QUEUE_NAME = "simple_queue";
public static void main(String[] argv) throws Exception {
// 1.获取连接
Connection connection = ConnectionUtil.getConnection();
// 2.创建通道
Channel channel = connection.createChannel();
// 3.声明队列
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
// 4.定义消费者
DefaultConsumer consumer = new DefaultConsumer(channel) {
// 消息消费回调方法
@Override
public void handleDelivery(String consumerTag, Envelope envelope,
BasicProperties properties, byte[] body) throws IOException {
String msg = new String(body);
System.out.println("消费者接收消息:" + msg);
}
};
// 5.监听队列(第二个参数:自动确认消息)
channel.basicConsume(QUEUE_NAME, true, consumer);
}
}
关键说明
queueDeclare:声明队列,参数依次为:队列名、是否持久化、是否独占、是否自动删除、附加参数。basicPublish:发送消息,参数依次为:交换机名(简单模型为空)、队列名、消息属性、消息体。basicConsume:监听队列,消费者启动后会一直监听,直到手动停止;自动确认模式下,消息被消费后会立即从队列移除。
6.2 工作队列模型(Work Queue)
适用于 "任务分发" 场景:多个消费者监听同一个队列,生产者发送的消息会被轮询分配给不同消费者,实现任务负载均衡。核心优化点:
- 消息持久化:避免 RabbitMQ 宕机后消息丢失。
- 公平分发:设置
basicQos(1),让消费者处理完一条消息后再接收下一条,避免能力弱的消费者积压任务。
6.3 发布 / 订阅模型(Fanout)
生产者将消息发送到交换机(Fanout 类型),交换机将消息广播到所有绑定的队列,所有订阅队列的消费者都能收到消息。核心特点:消息无路由规则,纯广播。
6.4 路由模型(Direct)
生产者发送消息到 Direct 交换机,交换机根据 "路由键" 将消息路由到指定队列,只有绑定了相同路由键的队列才能接收消息。适用于 "精准推送" 场景。
6.5 主题模型(Topic)
Direct 路由的升级版,路由键支持通配符(*匹配一个单词,#匹配多个单词),实现更灵活的路由规则,适用于 "模糊匹配" 场景。
七、总结
RabbitMQ 凭借高并发、低延时、易部署的特性,成为中小型系统消息中间件的首选。核心应用场景包括:异步通信、系统解耦、流量削峰、日志收集等。使用时需结合业务场景选择合适的消息模型,同时注意消息持久化、消费确认、死信队列等高级特性,保障消息传递的可靠性。