我们知道,生产者会先将消息发送给交换机,但是如果交换机此时没有匹配到相关的队列时,交换机中的消息就会出现丢失的问题。
那么,如何保证交换机中的消息不丢失呢?
mandatory 参数
当 basicPublish 方法的 mandatory 参数设为 true 时,如果交换器无法匹配到绑定的队列,那么 RabbitMQ 会调用 Basic.Return 命令将消息返回给生产者。
当 mandatory 参数设置为 false 时,若出现上述情形,则消息直接被丢弃。
那么,当 mandatory 参数设为 true 时,生产者如何获取被 RabbitMQ 返回的消息呢?这时,可以调用 channel.addReturnListener 来添加 ReturnListener 监听器实现。
备份交换机
备份交换机(Alternate Exchange)简称 AE,可以理解为备胎交换机。
生产者发送消息时,如果不设置 mandatory 参数,消息在未被正确路由的情况下会丢失;如果设置 mandatory 参数为 true,又需要添加 ReturnListener 的业务处理逻辑,生产者的代码将变得复杂。
如果既不想复杂化生产者的业务逻辑,又不想消息丢失,那么可以使用备份交换器。这样,它可以将未被路由的消息存储在 RabbitMQ 中,再在必要时去处理这些消息。
在声明交换机(exchangeDeclare 方法)时,添加 alternate-exchange 属性参数来实现。还需要声明该备份交换机,并给其绑定一个新的队列。
其实,备份交换器和普通的交换器没有太大的区别,为了方便使用,建议将 AE 设置为 fanout 类型。
注意: 消息被重新发送给备份交换机的路由键和从生产者发出的路由键是一样的。
对于备份交换机,需要考虑以下几种特殊情况:
- 如果设置的 AE 不存在,客户端和 RabbitMQ 服务端都不会出现异常,此时消息会丢失。
- 如果 AE 没有绑定任何队列,客户端和 RabbitMQ 服务端都不会出现异常,此时消息会丢失。
- 如果 AE 没有匹配到队列,客户端和 RabbitMQ 服务端都不会出现异常,此时消息会丢失。
- 如果同时使用了 AE 和 mandatory 参数,那么 mandatory 参数无效。