【发布时间】:2015-06-08 18:00:12
【问题描述】:
我计划将堆栈跟踪存储在 RabbitMQ 消息头中。消息头有大小限制吗?
【问题讨论】:
标签: rabbitmq spring-amqp
我计划将堆栈跟踪存储在 RabbitMQ 消息头中。消息头有大小限制吗?
【问题讨论】:
标签: rabbitmq spring-amqp
RabbitMQ 默认使用 AMQP 版本 0.9.1。根据第 31 页的AMQP protocol specification,field-table 可以包含 40 亿个条目:
long-uint = 4*OCTET
field-table = long-uint *field-value-pair
long-string 条目的长度可以达到 40 亿字节:
long-string = long-uint *OCTET ;长度+内容
一条 AMQP 消息分为 3 部分,标头、属性、消息。在属性部分,您可以放置特定于应用程序的信息。所以属性可能包含你的堆栈跟踪。
顺便说一句,标题和属性必须保持尽可能小,因为有performance penalty
【讨论】:
到目前为止的答案似乎表明在标题中塞入堆栈跟踪是没有问题的。
正如 John 在之前的回答中暗示的那样,几年前进行了一些更改,当标头大小超过 frame_max(默认情况下确实为 128kB)时,将导致抛出 IllegalArgumentException。
(The source code I'm referring to can be found here!)
作为一个(有趣的)旁注,这样做是为了防止一个问题,即具有超过最大帧大小的单个巨大标头的消息会导致客户端创建巨大的标头帧并将其传输到服务器,结果,服务器以frame_too_large 错误关闭连接,这会破坏所有打开的通道!
为了在标头中包含堆栈跟踪,您可以增加标头大小,或将其设置为 0 以表示“无限制”,但您应该注意,这并不是特别在大多数情况下是可取的(较大的值可能会提高吞吐量,而较小的值可能会提高延迟)。
【讨论】:
由于您使用的是 RabbitMQ,我猜您使用的是标准协议,即 AMQP。
在这种情况下,您不应该在标题中添加类似堆栈跟踪的内容,因为根据AMQP specification 3.2.1,标题用于standard delivery details:
标头部分包含有关通过 AMQP 网络传输消息的标准传递详细信息。如果标题部分被省略,则接收者必须为标题中的字段假定适当的默认值(或未设置值所暗示的含义),除非另外设置了其他目标或节点特定的默认值。
根据我的发现,规格并没有提及任何关于特定大小的内容,因此如果您愿意,可以在其中塞入堆栈跟踪 :)
【讨论】:
到目前为止的答案似乎表明在标题中填充堆栈跟踪是没有问题的。但是,我实际上尝试了这个,并遇到了这个问题:
Caused by: java.lang.IllegalArgumentException: Content headers exceeded max frame size: 163475 > 131072
at com.rabbitmq.client.impl.AMQCommand.transmit(AMQCommand.java:115) ~[amqp-client-5.7.3.jar:5.7.3]
在我看来,某处强制执行了 128kB 限制(默认情况下)。
【讨论】:
将 amqplib 客户端用于 nodejs 时,标头有 4k 字节的限制。超过此值时,您将收到异常“帧大小超过帧最大值”并且 cosumer 死亡。
【讨论】: