2019独角兽企业重金招聘Python工程师标准>>>
简介
当使用RabbitMQ发布消息时,消息又AMQP规范中的三个低层帧类型组成:
- Basic.publish方法帧;
- 内容头帧;
- 消息体帧;
这三种帧类型按顺序一起工作,以便消息传递时完好无损。
其中,内容头帧中的消息属性是一种预定义的值,这些值通过设置Basic.Properties数据结构进行指定:
- content-type属性:让消费者知道如何解释消息体;
- content-encoding属性:指示消息体使用某种特殊的方式进行压缩或编码;
- message-id和correlation-id属性:表示唯一消息标识和消息响应标识,用于在工作流程中实现消息跟踪;
- timestamp属性:表示消息创建时间;
- expiration属性:表示消息的过期时间;
- delivery-mode属性:将消息写入磁盘或内存队列;
- app-id和user-id属性:帮助追踪出现问题的消息发布者应用程序;
- type属性:表示发布者和消费者之间的契约;
- reply-to属性:实现响应消息的路由;
- headers属性:定义自由格式的属性和实现RabbitMQ路由;
不建议使用的属性有:priority和cluster-id属性。
content-type属性介绍
content-type属性用于描述消息体的数据格式,如同各种标准化的HTTP规范,content-type传输消息体也可以使用MIME类型。例如,如果应用程序正在发送JSON序列化的数据值,那么可以将content-type设置为application/json。如果客户端支持自动序列化,可以在消费消息时,帮你进行序列化的工作。
content-encoding属性
默认情况下,通过AMQP发送的消息不会被压缩。但如果在消息数量较大的场景下,则可能会希望对消息进行压缩。AMQP提供了content-encoding属性设置压缩编码:
不要混淆content-encoding和content-type。与HTTP规范一样,content-encoding用于指示content-type之外的某种编码级别。它是一个修饰字段,通常用于表明消息体的内容已经使用gzip或其他形式的压缩方式进行了压缩。
结合content-type属性后,content-encoding属性使消费者应用程序能够基于一种明确的契约与发布者进行交互。
message-id和correlation-id属性
在AMQP规范中,message-id和correlation-id是“应用级别使用”的属性,原则上,你可以利用它们实现任何目的。这两个字段允许255个字节的UTF-8编码数据,并以未压缩的方式存储在Basic.Properties数据结构中。
message-id属性可以存放消息的唯一标识。
correlation-id属性可以指定该消息是另一个消息的响应(另一个消息的标识)。
timestamp属性
通过使用timestamp属性来指示消息的创建时间,消费者可以用来评估消息投递过程的性能。
该属性没有时区上下文,因此建议在所有消息中使用UTC或其他统一的时区。
expiration属性
如果消息没有被消费,expiration属性会告诉RabbitMQ何时应该丢弃消息。它的格式是一个短字符串,允许255个字符。
想要利用expiration属性来实现RabbitMQ消息的自动过期,它必须包含一个UNIX纪元时间或整数时间戳,然后把它存储为字符串。如果把一个已经超时的消息发布到服务器,则该消息不会被路由到任何队列,而是被直接丢弃。
RabbitMQ还有一个可以让消息过期的功能,在声明队列时,将一个x-message-ttl参数和队列定义在一起,这个值也是一个UNIX纪元时间戳,精度是毫秒,数据类型是整数值。
delivery-mode属性
delivery-mode可能是很多人研发人员最感兴趣的一个属性,因为它关乎与RabbitMQ的性能。它表示在将消息投递给任何消费者之前,是否希望先将它持久化到磁盘上,delivery-mode又2个值:1表示非持久化消息,2表示持久化消息。
不要把消息持久化和队列持久化(durable)混淆,队列持久化是告诉RabbitMQ队列的定义在重启RabbitMQ后是否仍然有效。只有设置了消息的delivery-mode才会告诉RabbitMQ消息是否应该被持久化。一个队列可能包含持久化和未持久化的消息。
前面说过delivery-mode属性关乎性能,是因为内存IO比磁盘IO要快,因此将delivery-mode设置为1将会尽可能降低消息投递的延迟性。
尽管这可以保证RabbitMQ崩溃时消息不会丢失,但是它存在性能和伸缩性的问题,设置为持久化将会对消息投递和性能有着很大的影响。
app-id和user-id属性
app-id和user-id属性提供了关于消息的另一层信息,可以携带一些信息以便消费者应用程序在处理消息之前进行验证。
app-id属性在AMQP规范中定义为“短字符串”,最多允许UTF-8字符。在生成消息时可以使用app-id传递特定API和版本号。可加强使用app-id可以更容易地追踪恶意消息的来源。
user-id属性一般用于存放已经登录的用户信息。
type属性
type属性被定义为“消息类型名称”,一般可以用于描述消息中的内容,应用程序可以根据它来确定如何处理一个消息。
创建自描述消息时,type属性非常有用,它可用于指定记录类型或外部定义文件(使用Google的Protobuf)。
reply-to属性
使用reply-to可以构件一个用来恢复消息的私有响应队列。这个定义中有大多的不明确性,所以使用起来需谨慎。
headers属性
headers属性是key-value结构,允许用户自定义任意的key和value。
key可以是ASCII或Unicode字符串,最大长度为255个字符。value可以是任何有效的AMQP值类型。
与其他属性不同,header属性允许你添加任何想要添加的数据到消息头表中。并且,RabbitMQ可以根据headers表中填充的值来路由消息,而不需要依赖路由键。
priority属性
截至3.5.0版本,RabbitMQ已经按照AMQP规范实现了priority字段,它的值被定义为0~9之间。用于指定队列中消息的优先级。
priority字段实现为无符号字节,所以优先级可以是0~255,但优先级应该被限制在0~9之间。
不能使用的属性:cluster-id/reserved
cluster-id属性在AMQP0-8中定义的,但随后被删除。
AMQP0-9-1将其重命名为reserved,并声明它必须为空,虽然RabbitMQ目前没有根据规范要求它是空的,但你最好完全规避它。