【RabbitMQ doc】可靠性指南

可靠性指南

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

什么状况下会失败?

网络问题多是最多见的失败状况。除了网络失败,防火墙还会中断空闲链接,并且网络失败不必定可以like检测获得。node

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

链接失败

对于网络链接失败,客户端会创建新的链接。以前链接上的通道会被自动关闭,而后在从新打开。数据库

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

应答和确认

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

acknowledgement能够双向应用——容许consumer向server说明它已收到/处理了一条消息,也容许producer作一样的事情。RabbitMQ将后一种状况叫作confirm(确认)负载均衡

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

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

相似,broker只有在接管了消息以后才会进行确认。ui

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

使用心跳检测失效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

相关文章
相关标签/搜索