生产者消息丢失的场景
生产者发送消息的流程如下:首先生产者和RabbitMQ服务器建立连接,然后创建信道,通过信道发送消息给RabbitMQ服务器,RabbitMQ服务器接收到消息后交由交换机进行消息存储,交换机根据不同策略将消息路由到指定队列中。在此过程中,可能会存在以下消息丢失的场景:
- 在发送消息的过程中生产者和RabbitMQ服务连接断开。
- 在发送消息的过程中信道关闭
- RabbitMQ接收到消息后但是无法匹配到合适的交换机进行消息处理
- 交换机接收到消息后无法将消息按照相关策略路由到指定队列中
- 消息存放到队列中,但是一致没有消费者消费,并且消息存放时间超过了设置的过期时间,消息被过期丢失
按照上述消息丢失场景可以划分为三种情况:消息无法到达RabbitMQ、RabbitMQ无法将消息存放的队列中、消息过期丢失
消息无法到达RabbitMQ
上述已经分析了消息无法从生产者发送给你RabbitMQ的两种情况,分别是连接端口和信道关闭。
连接断开
测试方法:生产者重复发送消息,在消息发送的过程中将RabbitMQ服务停止。
测试结果:生产者提示异常
Exception in thread “main” com.rabbitmq.client.AlreadyClosedException: connection is already closed due to connection error;
通过上述测试内容不难发现,如果连接断开则生产者将在消息发送的过程中提示异常,因此可以通过捕获异常的方式进行消息存储,避免消息丢失。
信道关闭
测试方法:生产者重复发送消息,开启一个线程,在一段时间后将信道关闭。
测试结果:生产者提示异常
Exception in thread “main” com.rabbitmq.client.AlreadyClosedException: channel is already closed due to clean channel shutdown; protocol method: #method<channel.close>(reply-code=200, reply-text=OK, class-id=0, method-id=0)
通过上述测试内容发现信道关闭和连接断开类似,生产者都能接收到异常信息。本测试也可以侧面说明,信道是非线程安全的,不建议去在不同线程间使用相同信道。由于信道是逻辑连接,因此信道关闭后可以通过连接再次创建信道。
RabbitMQ无法将消息入队
这种消息丢失的场景是指消息被RabbitMQ接收到了,因此针对生产者而言,消息已经成功发送了。单论消息发送的职责,生产者已经完成了;但是不可否认的情况话,RabbiMQ合法的接收到消息后已经可能存在消息丢失的情况,例如处理该消息的交换机不存在,消息无法按照规则路由到相关队列中。
交换机不存在
测试方法:消息发送的过程中写一个不存在的路由名称。
测试结果:生产者提示异常:
Exception in thread “main” com.rabbitmq.client.AlreadyClosedException: channel is already closed due to channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no exchange ‘sample_exchangetest’ in vhost ‘/’, class-id=60, method-id=40)
虽然生产者提示了该条异常,但是这是在第二次发送信息时提示的异常,也就是说在第一次给不存在的交换机发送消息时,生产者并未抛出异常,当第一条消息发送后,由于不存在相关交换机,则生产者将将该发送消息的信道关闭,进而在第二次通过该信道发送消息的时候提示信道关闭异常.
无匹配队列
测试方法:消息发送的过程中设置一个无法匹配到队列的路由键。
测试结果:生产者持续发送消息,未出现异常,但是队列中不存在生产者发送的消息。
当消息按照设置规则发送给相关交换机,但是交换机无法根据消息携带的路由键匹配到队列中,此时消息无法存储到队列中,消费者无法消费这些消息。值得注意的是,无匹配队列这种情况发生时,并未向上述几种情况生产者出现异常提示。所以无论生产者无法通过异常监听的方式得知消息发送失败!为此RabbitMQ提供了mandatory属性配置实现当队列不可达时生产者接收到返回消息。mandatory详细讲解见后文。文章来源:https://www.toymoban.com/news/detail-631091.html
消息过期丢失
测试方法:在发送消息的过程中设置过期时间。队列无消费者监听,等到消息过期。
测试结果:消息过期丢失,生产者无法获取消息丢失事件。
消息的过期时间设置见: RabbitMQ 过期时间(TTL)文章来源地址https://www.toymoban.com/news/detail-631091.html
消息丢失场景对比
场景 | 是否发生异常 |
---|---|
连接断开 | 是 |
信道关闭 | 是 |
交换机不存在 | 是 |
无匹配队列 | 否 |
消息过期丢失 | 否 |
到了这里,关于RabbitMQ 生产者-消息丢失 之 场景分析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!