RabbitMQ AMQP.BasicProperties.Builder值

在RabbitMQ / AMQP Java客户端中,可以创build一个AMQP.BasicProperties.Builder ,并使用它build()一个AMQP.BasicProperties实例。 这个构build的属性实例可以用于各种重要的事情。 这个构build器类有许多“构build器”风格的方法可用:

 BasicProperties.Builder propsBuilder = new BasicProperties.Builder(); propsBuilder .appId(???) .clusterId(???) .contentEncoding(???) .contentType(???) .correlationId(???) .deliveryMode(2) .expiration(???) .headers(???) .messageId(???) .priority(???) .replyTo(???) .timestamp(???) .type(???) .userId(???); 

我正在寻找这些builer方法帮助“build立”的领域, 最重要的是,每个领域有什么有效的价值 。 例如,什么是clusterId ,它的有效值是什么? 什么是type ,它的有效值是什么? 等等。

我已经花了整整一个早上去淘洗:

  • Java客户端文档 ; 和
  • Javadocs ; 和
  • RabbitMQ完整参考指南 ; 和
  • AMQP规范

在所有这些文档中,我找不到明确的定义(除了模糊地解释哪些prioritycontentEncodingdeliveryMode是什么)每个这些字段是什么,以及它们的有效值是什么。 有人知道吗? 更重要的是,是否有人知道这些甚至logging在哪里? 提前致谢!

通常我用非常简单的方法来记忆一些东西。 我将在下面提供所有细节,但这里是BasicProperties字段和值的简单图片。 我也试着正确地突出显示队列/服务器和应用程序上下文。

在这里输入图像说明

如果你想让我加强一点 – 只需要点评一下。 我真正想要的是提供一些视觉的关键和简化的理解。

高级描述 ( 来源1 , 来源2 ):

请注意Clust ID已被弃用,所以我将排除它。

  • 应用程序ID – 生成消息的应用程序的标识符。
    • 上下文:应用程序使用
    • 值:可以是任何string。
  • 内容编码 – 消息内容编码
    • 上下文:应用程序使用
    • 值:MIME内容编码(例如application / json)
  • 内容types – 消息内容types
    • 上下文:应用程序使用
    • 值:MIME内容types(例如gzip)
  • 相关ID – 与此相关的消息,例如,这个消息是什么请求的回复。 鼓励应用程序使用此属性,而不是将此信息放入消息有效内容中。
    • 上下文:应用程序使用
    • 价值:任何价值
  • 传递模式 – 消息是否应该保存到磁盘?
    • 上下文:队列实现使用
    • 价值:非持续性(1)或持久性(2)
  • 到期 – 消息过期后将被删除。 到期字段的值描述了以毫秒为单位的TTL周期。 请看下面的细节。
    • 上下文:队列实现使用
  • 标题 – 任意应用程序特定的消息标题。
    • 上下文:应用程序使用
  • 消息ID – 消息标识符作为string。 如果应用程序需要识别消息,则build议他们使用此属性,而不是将其放入消息有效内容中。
    • 上下文:应用程序使用
    • 价值:任何价值
  • 优先 – 消息优先。
    • 上下文:队列实现使用
    • 值:0到9
  • ReplyTo – 队列名称其他应用程序应该发送响应。 通常用于命名应答队列(或任何其他标识符,帮助消费者应用程序指示其响应)。 鼓励应用程序使用此属性,而不是将此信息放入消息有效内容中。
    • 上下文:应用程序使用
    • 价值:任何价值
  • 时间戳 – 发送消息时刻的时间戳。
    • 上下文:应用程序使用
    • 价值:自大纪元以来的秒数。
  • types – 消息types,例如这个消息代表什么types的事件或命令。 build议由应用程序使用,而不是将此信息包含在消息有效内容中。
    • 上下文:应用程序使用
    • 值:可以是任何string。
  • 用户标识 – 可选的用户标识。 由RabbitMQ根据实际的连接用户名进行validation。
    • 上下文:队列实现使用
    • 价值:应该被authentication的用户。

顺便说一句,我终于成功地审查了最新的服务器代码( rabbitmq-server-3.1.5 ),rabbit_stomp_test_util.erl中有一个例子:

  content_type = <<"text/plain">>, content_encoding = <<"UTF-8">>, delivery_mode = 2, priority = 1, correlation_id = <<"123">>, reply_to = <<"something">>, expiration = <<"my-expiration">>, message_id = <<"M123">>, timestamp = 123456, type = <<"freshly-squeezed">>, user_id = <<"joe">>, app_id = <<"joe's app">>, headers = [{<<"str">>, longstr, <<"foo">>}, {<<"int">>, longstr, <<"123">>}] 

很高兴知道有人想知道所有的细节。 因为在可能的情况下使用众所周知的消息属性要好得多,而不是在消息体中放置信息。 顺便说一下,基本的消息属性远不是清楚而有用的。 我会说使用自定义的更好。

在这里输入图像说明

很好的例子 ( 来源 )

在这里输入图像说明

更新 – 过期字段

重要说明: 到期属于队列上下文。 所以消息可能会被服务器丢弃。

在这里输入图像说明

自述文件说:

expiration是短暂的; 因为RabbitMQ会期望这是一个编码的string,我们翻译一个ttl到它的整数值的string表示。

资料来源:

  • 其他来源1
  • 其他来源2

写作时:

  1. 最新的AMQP标准是AMQP 1.0 OASIS标准 。
  2. 最新版本的RabbitMQ是3.1.5(服务器和客户端),声称支持AMQP 0.9.1 (pdf和XML模式压缩)。
  3. RabbitMQ提供了自己的协议描述,如XML模式,包括扩展 (即非标准),加上没有扩展的XML模式 (与通过(2)链接的模式相同)和pdf文档 。

在这个答案中:

  • (3)中的链接是细节的主要来源
  • (2)如果(3)不充分,pdf文件被用作辅助细节
  • 如果(2)不足,源代码(java客户端,erlang服务器)将作为三级细节使用。
  • (1)通常不被使用 – 协议和模式已经(相当)显着地由OASIS发展,应该适用于未来版本的RabbitMQ,但现在不适用。 (1)的两个例外是contentTypecontentEncoding文本描述 – 这是安全的,因为这些是AMQP 1.0中具有良好描述的标准字段。

下面的文字是从这些资料中解释出来的,使我更加简洁明了些。

  • content-type (AMQP XML type =“shortstr”; java type =“String”):可选。 消息的应用程序数据部分(主体)的RFC-2046 MIMEtypes。 可以包含一个字符集参数,用于定义所使用的字符编码:例如'text / plain; 字符集=“UTF-8””。 在内容types未知的情况下,内容types不应该被设置,允许接收者确定实际的types。 在已知该部分是真正不透明的二进制数据的情况下,应将内容types设置为应用/八位字节stream。
  • 内容编码 (AMQP XML type =“shortstr”; java type =“String”):可选。 当存在时,描述应用于应用数据的附加内容编码,并且因此需要应用什么解码机制来获得由内容types头部字段引用的媒体types。 主要用于允许压缩文档而不会丢失其基础内容types的标识。 内容types的修饰符,按照RFC 2616的第3.5节进行解释。有效的内容编码在IANA处注册。 实现不应该使用压缩编码,除非保持与最初与其他协议一起发送的消息兼容,例如HTTP或SMTP。 实现不应该指定多个内容编码值,除非与最初与其他协议一起发送的消息兼容,例如HTTP或SMTP。
  • 标题 (AMQP XML type =“table”; java type =“Map”):可选。 一个应用程序指定的标题参数列表及其值。 这些可能被设置为仅供应用使用。 此外,还可以使用“标题交换types”创build队列 – 在创build队列时,会为其提供一系列要匹配的标题属性名称,每个标题名称都要匹配,以便通过标题发送到此队列-匹配。
  • deliveryMode (RabbitMQ XML type =“octet”; java type =“Integer”): 1 (非持久性)或2 (持久性)。 只适用于实现持久性的队列。 持久的消息被安全地保存在磁盘上,并且即使存在严重的networking故障,服务器崩溃,溢出等,也能保证被传送。
  • 优先级 (AMQP XML type =“octet”; java type =“Integer”):相对的消息优先级( 0到9 )。 高优先级的消息是[可能? – GB]在相同的消息队列中等待的优先级较低的消息之前发送。 当消息必须被丢弃以保持特定的服务质量水平时,服务器将首先丢弃低优先级的消息。 只适用于执行优先级的队列。
  • correlation-id (AMQP XML type =“octet”; java type =“String”):可选。 对于应用程序使用,没有正式的(RabbitMQ)行为。 可用于标记或识别客户端之间的消息的客户端特定的标识。
  • replyTo (AMQP XML type =“shortstr”; java type =“String”):可选。 对于应用程序使用,在请求消息中使用时,没有正式的(RabbitMQ)行为,但可以保存专用响应队列的名称。 要发送回复的节点的地址。
  • 到期 (AMQP XML type =“shortstr”; java type =“String”):可选。 (3)中的RabbitMQ AMQP 0.9.1模式声明“对于实现使用,没有正式的行为”。 来自(2)的AMQP 0.9.1模式pdf规定了这个消息被认为是过期的绝对时间。 但是, 这两个描述必须被忽略,因为这个TTL链接和客户端/服务器代码表明以下是真实的。 从客户端,过期只能通过BasicProperties的自定义应用程序初始化来填充。 在服务器上,这是用来确定从服务器上收到消息的点起,在排队之前的TTL。 服务器select(1)消息TTL(客户端BasicProperties过期作为相对时间,以毫秒为单位 )和(2)队列TTL(以毫秒为单位configurationx-message-ttl )的最小值来selectTTL。 格式:string引用的整数,表示毫秒数; 从服务器收到消息到期的时间。
  • message-id (AMQP XML type =“shortstr”; java type =“String”):可选。 对于应用程序使用,没有正式的(RabbitMQ)行为。 如果设置,则消息生产者应将其设置为全局唯一值。 在将来(AMQP 1.0),如果message-id的值与发送到同一节点的先前收到的消息的值匹配,代理可以将消息丢弃为重复。
  • timestamp (AMQP XML type =“timestamp”; java type =“java.util.Date”):可选。 对于应用程序使用,没有正式的(RabbitMQ)行为。 这个消息被创build的绝对时间。
  • types (AMQP XML type =“shortstr”; java type =“String”):可选。 对于应用程序使用,没有正式的(RabbitMQ)行为。 [将消息描述为/属于特定于应用程序的“types”或“表单”或“业务事务” – GB]
  • userId (AMQP XML type =“shortstr”; java type =“String”):可选。 XML模式状态“对于应用程序使用,没有正式(RabbitMQ)的行为” – 但我相信这已经改变了最新版本(继续阅读)。 如果设置,则客户端将该值设置为负责生成消息的用户的标识。 来自RabbitMQ :如果此属性由发布者设置,则其值必须等于用于打开连接的用户的名称(即,发生validation以确保其是连接/经过身份validation的用户)。 如果未设置用户标识属性,则发布者的标识将保持私有状态。
  • appId (RabbitMQ XML type =“shortstr”; java type =“String”):可选。 对于应用程序使用,没有正式的(RabbitMQ)行为。 创build应用程序ID。 可以由生产者填充并由消费者阅读。 (查看R-MQ服务器代码,尽pipe“webmachine-wrapper”插件提供了一个脚本和匹配的模板来创build一个webmachine–pipe理员可以在这个脚本中提供一个appId),这完全不会被服务器使用。
  • cluster id (RabbitMQ XML type =“N / A”; java type =“String”): 在AMQP 0.9.1中不赞成使用 – 即没有使用。 在以前的版本中,是群集内路由标识符,供群集应用程序使用,不应由客户端应用程序使用(即未填充)。 但是,这已被弃用,并从当前模式中删除,不被R-MQ服务器代码使用。

正如你上面看到的,绝大多数这些属性没有枚举/约束/推荐值,因为它们是“应用程序只使用”,不被RabbitMQ使用。 所以你有一个容易的工作。 您可以自由地编写/读取对您的应用程序有用的值 – 只要它们匹配数据types并编译:)。 ContentTypecontentEncoding按照标准的HTTP使用。 DeliveryModepriority是受限制的数字。

注意:对于AMQP.BasicProperties,有用但简单的常量可在类MessageProperties中使用 。

干杯:)

更新上传:

非常感谢Renat(请参阅注释),我们查看了rabbit_amqqueue_process.erl中的erlang服务器代码以及RabbitMQ TTL Extensions to AMQP的文档。 消息到期(生存时间)可以被指定

  • 每队列通过:

     Map<String, Object> args = new HashMap<String, Object>(); args.put("x-message-ttl", 60000); channel.queueDeclare("myqueue", false, false, false, args); 
  • 或每封邮件通过:

     byte[] messageBodyBytes = "Hello, world!".getBytes(); AMQP.BasicProperties properties = new AMQP.BasicProperties(); properties.setExpiration("60000"); channel.basicPublish("my-exchange", "routing-key", properties, messageBodyBytes); 

在这里,ttl / expiration以毫秒为单位,所以每种情况下都是60秒。 已经更新了以上定义的过期来反映这一点。

AMQP规范为属性定义了一个通用的,可扩展的模型。

AMQP属性在概念上有些类似于HTTP标头,因为它们表示关于有问题的消息的元数据。 就像在HTTP中一样,它们被分别构build到消息负载。 但他们基本上是一个关键/价值的地图。

像RabbitMQ这样的代理会解释某些消息属性,如expiration以增加额外的供应商特定的值(在这种情况下, 执行TTL )。

但最终,AMQP属性只是一大堆键/值对,如果您select这样做,可以安全地与每封邮件一起发送。 你的AMQP经纪人的文件将告诉你他们特别解释哪些和如何发送你自己的。

所有这一切说,如果你首先提出这个问题,那么你可能根本就不用担心它们。 您将能够成功地发送消息,而不必担心设置任何消息属性。