本文参考以下链接摘录翻译:
https://www.rabbitmq.com/tutorials/amqp-concepts
消息确认(Message Acknowledgements)
消费者应用,就是接收和处理消息的应用。它们偶尔会处理个别消息失败,断开与服务器之间的连接或许多其他失败。
也可能有网络问题导致的问题。这些情况提出了一个问题:消息代理应该在何时删除消息?AMQP 0-9-1让消费者来控制消息的删除时机。有2中确认模式:
- 在消息代理将一条消息发送给一个应用后删除这条消息(使用basic.deliver 或 basic.get-ok 方法)【自动确认模式】
- 在消费者应用发送回确认后删除(使用basic.ack方法)【显式确认模式】
使用显式确认时,应用选择何时发送确认。可以在收到消息后马上发送,可以在将消息保存到数据库尚未处理前发送,或者在完全处理完一条消息后发送(例如,成功获取了一个网络页面,处理完并存储到某个持久化数据库)。
如果一个消费者挂掉了,没用发回确认,消息代理会将消息重新发送给另一个消费者,如果正好没有可接收消息的消费者,消息代理会等到至少有一个消费者订阅这个队列,然后尝试重新发送消息给这个消费者。
拒绝消息(Rejecting Messages)
当一个消费者应用收到一条消息,消息处理可能成功或失败。一个应用可以通过拒绝一条消息来告知消息代理:消息处理失败了(或者当前不能完成消息处理)。当拒绝一条消息,应用可以叫消息代理删除消息或将消息重新放入队列。当一个队列只有一个消费者时,确保不要因为同一个消费者拒绝和重新入队一条消息,而产生无限的消息发送循环。
反向确认(Negative Acknowlegements)
拒绝消息使用basic.reject方法。basic.reject有一个限制:无法一次拒绝多条消息,但ack可以一次确认多条消息。尽管如此,如果你使用RabbitMQ,可以用RabbitMQ的反向确认【negative acknowlegements 或 nacks】来实现。
预取消息(Prefetching Messages)
对于多个消费者共享一个队列的情形,在发送下一次确认之前,指定每次发送多少条消息给一个消费者是有用的。这可以实现简单的负载均衡,或者增加吞吐量,如果想批量发送消息的话。例如,一个生产者应用每分钟发送消息,由于它工作的特质。
消息属性和负载(Message Attributes and Payload)
AMQP 0-9-1模型中的消息有属性。有些属性很常见,应用开发者不必关心它们的名字。下面是一些属性名:
- Content Type
- Content encoding
- Routing key 路由键
- Delivery mode(persist or not) 发送模式,持久化或否
- Message priority 消息优先级
- Message publishing timestamp 消息发布时间戳
- Publisher application id 发布者应用id
一些属性被AMQP代理使用,但绝大多数都得由接收消息的应用去解析。有些熟悉是可选得,叫做头(headers)。它们与HTTP中的X-Headers类似。消息属性在消息发布时设置。
消息也有一个负载(即消息携带的数据),在AMQP代理中,负载是一个透明的字节数组。消息代理不会审查或修改负载。消息可以只包含属性,不包含负载。为了将结构化数据设置为负载,一般用序列化格式,如JSON,Thrift, Protocol Buffers和MessagePack来序列化。经常使用content-type和content-encoding来说明数据格式,原则上是这样。
消息可以发布为持久化的,这时消息代理会把消息保存到磁盘。如果代理服务器被重启了,系统会确保收到的持久化消息不会丢失。简单地发布一条消息到一个持久化的交换机或持久化的队列,不会让这条消息被持久化。消息的持久化完全依赖消息自身的持久化模式。将消息发布为持久化会影响性能(就像数据存储,持久化带来一定的性能消耗)。
待续。。。