消息可靠性投递
默认情况下,发送消息的操作是不会返回任何消息给生产者的,也就是说,默认情况下生产者是不知道消息有没有正确地到达服务器。
那么如何解决这个问题呢?
对此,RabbitMQ中有一些相关的解决方案:
1.使用事务机制来让生产者感知消息被成功投递到服务器
2.通过生产者确认机制实现
在RabbitMQ中,所有确认消息可靠性投递的机制都会对性能产生一定影响,如使用不当,可能会对吞吐量造成重大影响,只有通过执行性能基准测试,才能在确定性能与可靠性投递之间的平衡。
事务机制
事务的实现主要时对信道(Channel)的设置,主要方法有三个:
- channel.txSelect()声明事务模式
- channel.txComment()提交事务
- channel.txRollback()回滚事务
交互流程
- 客户端发送给MQ节点tx.Select(开启事务模式)
- MQ节点返回tx.Select-ok(开启事务模式OK)
- 客户端推送消息
- 客户端发送事务提交tx.Commit
- 服务端返回tx.Commit-OK
在RabbitMQ中,所有确认消息可靠性投递的机制都会对性能产生一定影响,如使用不当,可能会对吞吐量造成重大影响,只有通过执行性能基准测试,才能在确定性能与可靠性投递之间的平衡。
Confirm确认机制
消息的确认,是指生产者投递消息后,如果Broker收到消息,则会给我们生产者一个应答。
生产者进行接收应答,用来确定这条消息是否正常的发送到Broker,这种方式也是消息的可靠性投递的核心保障。
如何实现Confirm确认消息?
- 在channel上开启确认模式:channel.confirmSelect()
- 在channel上添加监听:addConfirmListener,监听成功和失败的返回结果,根据具体的情况对消息进行重新发送、或记录日志等后续处理。
Return消息机制
Return Listener用于处理一些不可路由的消息。
消息生产者通过指定一个Exchange和RoutingKey,把消息送达到某一个队列中去,然后消费者监听队列,进行消费处理操作!
但在某些情况下,如果我们在发送消息时,指定的路由Key路由不到,这个时候我们需要监听这种不可达的消息,就要使用Return Listener。
在基础API中有一个关键的配置项:
Mandatory:如果为true,则监听器会接收路由不可达的消息,然后进行后续处理,如果为false,那么broker端自动删除该消息。
备份交换机
备份交换机可以理解为 RabbitMQ 中交换机的“备胎”,当我们为某一个交换机声明一个对应的备份交换机时,就是为它创建一个备胎,当交换机接收到一条不可路由消息时,将会将这条消息转发到备份交换机中,由备份交换机来进行转发和处理,通常备份交换机的类型为 Fanout ,这样就能把所有消息都投递到与其绑定的队列中,然后我们在备份交换机下绑定一个队列,这样所有那些原交换机无法被路由的消息,就会都进入这个队列了。当然,我们还可以建立一个报警队列,用独立的消费者来进行监测和报警。
Map<String,Object> arguments = new HashMap<>();
arguments.put("alternate-exchange",backupsExchangeName);
// 声明交换机
channel.exchangeDeclare(exchangeName,"topic",true,false,arguments);