4.19. 配置环队列
通常,AMQ Broker 中的队列使用先出(FIFO)语义。这意味着代理向队列的尾部添加信息,并将它们从头中删除。环队列是一种特殊类型的队列,包含指定的、固定数量的消息。当新消息到达但队列已包含指定数量的消息时,代理通过删除队列头来维护固定队列大小。
例如,假设环队列配置大小为 3,生成者按顺序发送消息 A、B、C 和 D。消息 C 到达队列后,队列中的消息数已达到配置的环大小。此时,消息 A 位于队列的头头,而消息 C 处于尾部。当消息 D 到达队列时,代理会将消息添加到队列的尾部。为了维护固定队列大小,代理会删除队列头的消息(即消息 A)。消息 B 现在位于队列的头。
4.19.1. 配置环队列 复制链接链接已复制到粘贴板!
以下步骤演示了如何配置环队列。
流程
-
打开 &
lt;broker_instance_dir> /etc/broker.xml配置文件。 要在没有设置显式环大小的匹配地址上为所有队列定义默认环大小,请在
address-setting元素中为default-ring-size指定一个值。例如:<address-settings> <address-setting match="ring.#"> <default-ring-size>3</default-ring-size> </address-setting> </address-settings><address-settings> <address-setting match="ring.#"> <default-ring-size>3</default-ring-size> </address-setting> </address-settings>Copy to Clipboard Copied! Toggle word wrap Toggle overflow default-ring-size参数对于定义自动创建队列的默认大小特别有用。default-ring-size的默认值为-1(即无大小限制)。要在特定队列上定义环大小,请将
ring-size键添加到queue元素。指定一个值。例如:Copy to Clipboard Copied! Toggle word wrap Toggle overflow
您可以在代理运行时更新 ring-size 的值。代理会动态应用更新。如果新的 ring-size 值小于前面的值,代理不会立即从队列头中删除消息,以强制实施新大小。发送到队列的新消息仍然强制删除旧的消息,但队列不会达到其新的大小,直到客户端通过正常方式使用消息。
4.19.2. 环队列故障排除 复制链接链接已复制到粘贴板!
本节介绍环队列的行为与其配置不同的情况。
In-delivery 消息和回滚
当消息发送到消费者时,消息处于"in-between"状态,其中消息在技术上不再在队列中,但尚未确认。消息会一直处于 in-delivery 状态,直到被消费者确认。处于 in-delivery 状态的消息无法从环队列中删除。
由于代理无法删除 in-delivery 消息,因此客户端可以将比环队列所允许的更多消息发送到环队列。例如,请考虑这种情况:
-
制作者将三个消息发送到配置了
ring-size="3"的环队列。 所有消息都会立即分配给消费者。
此时,
messageCount=3和 deliverCount=3。生产者向队列发送另一个消息。然后,消息被分配给消费者。
现在,
messageCount=4和deliverCount=4。消息计数4大于配置的环大小3。但是,代理需要允许这种情况,因为它无法从队列中删除发送的消息。现在,假设消费者已关闭,而不会确认任何消息。
在这种情况下,四个 in-delivery,未确认的消息会取消到代理,并以相反的顺序添加到队列的头。此操作将队列置于其配置的环大小上。由于环队列更喜欢在头上队列尾部的消息,因此队列丢弃了生产者发送的第一个消息,因为这是最后一个消息添加到队列的头头。事务或核心会话回滚的方式相同。
如果您直接使用核心客户端,或使用 AMQ Core Protocol JMS 客户端,您可以通过减少 consumerWindowSize 参数的值(默认为 1024 * 1024 字节)来最小化传输的消息数量。
调度的消息
当调度的消息发送到队列时,该消息不会立即添加到队列的尾部,如正常消息。相反,代理会将调度的消息保存在中间缓冲区中,并根据消息的详情调度消息以发送到队列的头。但是,调度的消息仍然反映在队列的消息计数中。与内发送的消息一样,此行为可能会显示代理没有强制执行环队列大小。例如,请考虑这种情况:
在 12:00 时,生成者发送消息
A给使用ring-size="3"配置的环队列。该消息被调度为 12:05。此时,
messageCount=1和scheduledCount=1。at 12:01,生成者将消息
B发送到同一环队列。现在,
messageCount=2和scheduledCount=1。at 12:02,生成者将消息
C发送到同一环队列。现在,
messageCount=3和scheduledCount=1。at 12:03,生成者将消息
D发送到同一环队列。现在,
messageCount=4和scheduledCount=1。队列的消息数现在是
4,大于 配置的环大小为3。但是,调度的消息还没有在队列中(即,它位于代理上,并被调度到队列中)。在计划的 12:05 交付时,代理会将消息放在队列的头头上。但是,由于环队列已达到其配置的大小,因此调度的消息A会立即被删除。
页面消息
与发送中调度的消息和消息类似,页面的消息不会计入代理所强制执行的环队列大小,因为消息实际上被记录在地址级别,而不是队列级别。一个 paged 消息在队列中没有技术,但它反映在队列的 messageCount 值中。
建议您不要将分页用于环队列的地址。相反,请确保整个地址可以容纳在内存中。或者,将 address-full-policy 参数配置为 DROP, BLOCK 或 FAIL。
其他资源
- 当您配置被动地址时,代理会创建环队列的内部实例。如需了解更多相关信息,请参阅 第 4.20 节 “配置 retroactive 地址”。