【RabbitMQ doc】可靠性指南

可靠性指南

本页面介绍如何使用AMQP和RabbitMQ的特性来达到可靠性传输——确保消息即使遇到失败的情况下也能够发送。

什么情况下会失败?

网络问题可能是最常见的失败情况。除了网络失败,防火墙还会中断空闲连接,而且网络失败不一定能够like检测得到。

除了连接性失败,broker和client应用可能会遇到硬件失败(或者软件崩溃)。即使是客户端应用一直在运行,逻辑错误也可能导致通道或者连接错误,这会强制客户端重新建立通道或者连接来恢复问题。

连接失败

对于网络连接失败,客户端会建立新的连接。之前连接上的通道会被自动关闭,然后在重新打开。

通常情况,遇到网络连接失败,连接会抛出异常来通知客户端。官方的Java和.NET客户端会提供额外的callback方法,让你接收连接失败的消息。【省略……】

应答和确认

消息在客户端和服务端之间传输时可能会遇到连接失败——它们可能正在系统缓存或者线路上被解析或者生成。传输中的消息需要被重传。应答(acknowledgement)让服务端和客户端知道什么时候重传。

acknowledgement可以双向应用——允许consumer向server说明它已收到/处理了一条消息,也允许producer做同样的事情。RabbitMQ将后一种情况叫做confirm(确认)

TCP为了确保数据包能被收到,会进行重传——这只是针对网络层。应答和确认表明消息已被收到并且被正确处理。应答消息既表明收到了消息,也表明了消息的所有者发生了转移。

acknowledgements因此具有如下意义——消费者应用只有在完成它应做的工作后才进行应答,比如记录进数据库,转发、打印到文件或任何其他地方。完成该操作后,broker可以释放掉该消息。

类似,broker只有在接管了消息之后才会进行确认。

应答保证消息至少有一次被送达。没有应答可能会导致消息在消息发布、消费操作时丢失,并且只能保证之多有一次被送达。

使用心跳检测失效TCP连接

在特殊的网络失败中,检测到TCP连接的失败需要相当长的时间(linux默认时间大约11分钟)。AMQP 0-9-1提供了心跳检测机制确保应用层可以发现中断的连接(也包括完全无响应的对端)。心跳检测还可以确保空闲连接不被中断。

 

Broker端(代理人)

为了避免消息丢失,需要处理broker的重启、broker的硬件故障、甚至极端情况下的broker崩溃。

为了确保消息和broker的属性在重启后仍然存在,需要将其写入磁盘。AMQP标准中有exchanges、queues的持久化概念,保证重启之后消息仍然存在。更多细节参见AMQP Concepts Guide

集群和高可用

如果要保证broker在重启后仍然存在,我们可以使用RabbitMQ的集群功能。集群中,所有定义(exchanges、bindings、users等等)在整个集群中镜像存在。队列请求默认只存在于单个节点,但可以根据情况镜像到某些甚至所有节点。队列请求对于所有节点都是可见可达的。

镜像队列将消息内容复制到整个配置好的集群节点上,容忍节点失效且无消息丢失。不过消费应用程序需要注意当队列出现问题后,consumer会被取消,之后他们会被重新消费。

 

Producer端

在需要confirm的情况下,从通道或连接失效中恢复的producer需要重新发送未接收到来自于broker的acknowledgements的消息。这可能存在消息重复,因为broker可能已经发送了confirm消息但producer没有收到。因此消费者应用需要去重,或者以幂等方式处理进入的消息。

确保消息已被路由

特定环境下,对于producer来说,需要确保消息已被路由到队列中(并不总是如此,在pub-sub发布订阅系统中,生产者只发布消息,如果没有消费者消费,消息将被丢弃)。

为了确保消息被路由到单个队列,消费者会声明目的队列,并直接发布给队列。如果消息需要以更复杂的方式路由,producer仍然需要确保消息至少路由到一个队列,可以设置basic.publish的强制标记,确保没有queues绑定的情况下,basic.return(包含回复代码以及一些文本说明)送回到客户端。

producer需要注意,向集群发布时,如果一个或多个目的队列有镜像存在,由于网络错误的原因,可能会导致延迟发生。

消费者

在网络失败情况下,消息可能会出现重复,消费者需要准备好处理它。可能情况下,最简单的方式是保证消费者以幂等方式处理消息,而不是去重。

如果某个消息发送达到消费者之后,重传给队列,RabbitMQ会设置重传标记。这表明消费者可能之前接收过该消息。与之对应的是,如果重传标记未设置,这可以保证消息是第一次被接收。因此,如果消息以幂等方式或去重方式处理比较困难,可以只处理带有重传标记的消息集合。

Consumer Cancel Notification

Under some circumstances the server needs to be able to cancel a consumer - since the queue it was consuming from has been deleted, or has failed over. In this case the consumer should consume again but be aware that it may see messages again which it has already seen.

Note that consumer cancel notification is a RabbitMQ extension to AMQP, and as such may not be supported by all clients.

 

Messages That Cannot Be Processed

If a consumer determines that it cannot handle a message then it can reject it using basic.reject (orbasic.nack), either asking the server to requeue it, or not (in which case the server might be configured todead-letter it instead.

 

分布式RabbitMQ

Rabbit 提供了两种分布式节点应对不可靠网络:federation和shovel。两种方式都采用了AMQP客户端方式,如果你配置(默认即是)了确认和应答,他们在特定情况下会进行消息重传。

当使用federation或shovel连接到集群,需要容忍节点失效。下游节点失效时,federation会自动分布连接到下游的集群。当上游节点失效时,为了连接到新的上游节点,你可以为一个upstream指定多个备用URIs,或者使用TCP负载均衡。

When using the shovel, it is possible to specify redundant brokers in a source or destination clause; however it is not currently possible to make the shovel itself redundant. We hope to improve this situation in the future; in the mean time a new node can be brought up manually to run a shovel if the node it was originally running on fails.

https://www.rabbitmq.com/reliability.html

转载于:https://my.oschina.net/u/259976/blog/741041

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值