持久化消息
指消息想要从Rabbit崩溃中恢复,那么消息必须:
- 把投递模式(delivery mod)设置为 2,即持久
- 发送到持久化的交换器
- 到达持久化的队列
如何保证消息发送成功
方法1
使用发送方确认机制,只有消息安全到达了队列后,RabbitMQ会向生产者发送一条确认消息,生产者可以根据确认消息进行相关函数的回调
方法2
如果消息没有匹配路由,则可以在发布消息的时候加入mandatory
参数,设置为true
,则未路由的消息可以返回给生产者,生产者可以通过添加ReturnListener
监听器来去获取返回的消息
方法3
通过声明备份交换器Alternate Exchange
可以在消息未匹配到路由的时候将消息转发到AE,备份交换器会通过相同的路由键
来去匹配 备份交换器本身所绑定的队列
注意事项
- 如果设置的备份交换器不存在,客户端和RabbitMQ服务端都不会出现异常,此时消息丢失
- 如果备份交换器没有绑定任何队列,客户端和RabbitMQ服务端都不会出现异常,此时消息丢失
- 如果备份交换器没有匹配到任何队列,客户端和RabbitMQ服务端都不会出现异常,此时消息丢失
- 如果备份交换器和 mandatory 参数一起使用,那么mandatory参数无效
如何保证消息接收成功
消费者接收到消息后,返回一个确认消息给MQ,否则不会向该消费者继续发送消息
消息生命周期
生产者
- 连接到RabbitMQ
- 获取信道
- 声明交换机
- 创建消息
- 发布消息
- 关闭信道
- 关闭连接
消费者
- 连接到RabbitMQ
- 获得信道
- 声明交换机
- 声明队列
- 把队列和交换机绑定起来
- 消费消息
- 关闭信道
- 关闭连接
消息设置过期时间
方法1
为队列中的所有消息都设置相同的过期时间,可以在声明队列的时候设置x-message-ttl
参数,单位是ms
方法2
为每条消息设置单独的过期时间,可以在生产者发布消息的时候设置Expiration
参数,单位为ms
区别
第一种一旦过期,就会从队列中抹去,因为队列中已过期的消息在队列总的头部,RabbitMQ只需要定期扫描头部消息是否过期
第二中消息过期,可能不会立刻从队列中删除,因为此时是在消息将要消费时,才判断是否过期
死信消息
产生死信消息一般有以下情况:
- 消息被拒绝(Basic.Reject/Basic.Nack),并设置requeue参数为false
- 消息过期
- 队列达到最大长度
如果所在的队列设置了参数dead-letter-exchange
,该参数值为 死信交换器的名称,既可以将死信消息转发到 死信交换器所绑定的 队列中(死信队列)