消息中间件RabbitMQ
文档链接:消息队列文档
消息队列面试题(转载):MQ面试题
MQ的定义
Rabbitmq系统最核心的组件是Exchange和Queue
消息队列,提供了FIFO的处理机制,具有缓存消息的能力。rabbitmq中,队列消息可以设置为持久化,临时或者自动删除。
MQ功能


三、MQ的分类
四、RabbitMQ
五、四大核心

六、六大核心(六大模式)
1. 简单模式
2. 工作模式
3. 发布订阅模式
4. 路由模式
5. 主题模式
6. 发布确认模式
七、工作原理
1. Broker : 接收和发布消息的应用,即消息实体
2. Wxchange:交换机(一个消息实体可以对应多交换机)
3. Queue: 队列 (一个交换机可以对应多个队列)
4. Channel :信道,即发消息的通道。 每一个生产者会与MQ之间都会建立一个连接Connection ,每一个链接里会有多个信道
5. Connection : 链接,每次调用MQ都会建立一个链接,链接里有包含多个信道,每次发消息只占用一个信道,而不占用整个连接
6. 绑定:每一个交换机与队列的链接就叫做绑定
八、生产者、消费者代码示例
依赖:
<!--指定 jdk 编译版本-->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<!--rabbitmq 依赖客户端-->
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>5.8.0</version>
</dependency>
<!--操作文件流的一个依赖-->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
</dependencies>
消息生产者:
public class Producer {
private final static String QUEUE_NAME = "hello";
public static void main(String[] args) throws Exception {
//创建一个连接工厂
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("182.92.234.71");
factory.setUsername("admin");
factory.setPassword("123");
//channel 实现了自动 close 接口 自动关闭 不需要显示关闭
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
/**
* 生成一个队列
* 1.队列名称
* 2.队列里面的消息是否持久化 默认消息存储在内存中
* 3.该队列是否只供一个消费者进行消费 是否进行共享 true 可以多个消费者消费
* 4.是否自动删除 最后一个消费者端开连接以后 该队列是否自动删除 true 自动删除
* 5.其他参数
*/
channel.queueDeclare(QUEUE_NAME,false,false,false,null);
String message="hello world";
/**
* 发送一个消息
* 1.发送到那个交换机
* 2.路由的 key 是哪个
* 3.其他的参数信息
* 4.发送消息的消息体
*/
channel.basicPublish("",QUEUE_NAME,null,message.getBytes());
System.out.println("消息发送完毕");
}
}
消息消费者
public class Consumer {
private final static String QUEUE_NAME = "hello";
public static void main(String[] args) throws Exception{
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("182.92.234.71");
factory.setUsername("admin");
factory.setPassword("123");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
System.out.println("等待接收消息.........");
//推送的消息如何进行消费的接口回调
DeliverCallback deliverCallback=(consumerTag,delivery)->{String message= new String(delivery.getBody());
System.out.println(message);
};//函数式接口,可使用拉姆达斯表达式
//取消消费的一个回调接口 如在消费的时候队列被删除掉了
CancelCallback cancelCallback=(consumerTag)->{
System.out.println("消息消费被中断");
};
/**
* 消费者消费消息
* 1.消费哪个队列
* 2.消费成功之后是否要自动应答 true 代表自动应答 false 手动应答
* 3.消费者未成功消费的回调
*/
channel.basicConsume(QUEUE_NAME,true,deliverCallback,cancelCallback);
}
}
九、工作模式
消息生产者向队列发送了大量的消息,消息停留在队列中,无法及时处理,这是需要有很多个消费者(线程)去处理。
注意:这里生产者发送的消息,消费者只能处理一次,即一条消息被工作线程A处理后,线程B不能再处理。 所以消息轮训分发
十、消息应答
为了保证消息在发送过程中不丢失,rabbitmq 引入消息应答机制,消息应答就是:消费者在接收到消息并且处理该消息之后,告诉 rabbitmq 它已经处理了,rabbitmq 可以把该消息删除了。
分类:分为自动应答和手动应答
自动应答: 消息发送后立即被认为已经传送成功,这种模式需要在高吞吐量和数据传输安全性方面做权衡
手动应答:共分为3个方法
A. Channel.basicAck(用于肯定确认) RabbitMQ 已知道该消息并且成功的处理消息,可以将其丢弃了
B. Channel.basicNack(用于否定确认)
C. Channel.basicReject(用于否定确认)
与 Channel.basicNack 相比少一个参数 不处理该消息了直接拒绝,可以将其丢弃了
手动应答又分为批量应答和非批量应答,写代码推荐使用非批量应答,可以避免丢失消息。 但批量应答速度会和快
手动应答的好处是可以批量应答并且减少网络拥堵
multiple 的 true 和 false 代表不同意思
true 代表批量应答 channel 上未应答的消息
比如说 channel 上有传送 tag 的消息 5,6,7,8 当前 tag 是8 那么此时
5-8 的这些还未应答的消息都会被确认收到消息应答
false 同上面相比
只会应答 tag=8 的消息 5,6,7 这三个消息依然不会被确认收到消息应答
十一、消息的重新入队
如果出现了消息丢失,如何处理呢?
队列发送2条消息给消费者C1和C2,消息A发送给C1, 消息B发送给C2,在发送过程中,C1突然断开连接,C2正常处理并应答了,此时队列接收不到C1的应答,队列里的消息A暂未删除,队列会将A重新发送给C2进行处理。从而避免消息丢失。 核心思想就是消息自动重新入队
如果消费者由于某些原因失去连接(其通道已关闭,连接已关闭或 TCP 连接丢失),导致消息未发送 ACK 确认,RabbitMQ 将了解到消息未完全处理,并将对其重新排队。如果此时其他消费者可以处理,它将很快将其重新分发给另一个消费者。这样,即使某个消费者偶尔死亡,也可以确保不会丢失任何消息。
十二、消息的发布确认
消息的确认分两部分:
rabbitMQ 确认生产者投递的消息 和 消费者确认 rabbitMQ 服务器的消息(消息应答)
rabbitMQ 确认生产者投递的消息
首先说 RabbitMQ 对生产者的确认,总共分为两种模式分别为 同步模式 与 异步模式
同步模式分为 单条消息确认 与 批量确认。
1. 单条消息确认: channel.waitForConfirms() 普通发送方确认模式;消息到达交换器,就会返回true。
2. 批量消息确认: channel.waitForConfirmsOrDie()批量确认模式;使用同步方式等所有的消息发送之后才会执行后面代码,只要有一个消息未到达交换器就会抛出IOException异常。
异步模式为生产者异步监听消息确认。
异步监听消息确认:channel.addConfirmListener()异步监听发送方确认模式。
消费者对RabbitMQ 消息确认。总共分为两种方式 分别为 手动确认 和 自动确认。 即消费者消费消息后对borker的自动应答和手动应答
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)