4.19. 配置环队列
通常,AMQ Broker 中的队列使用 first-in 和 first-out(FIFO)语法。这意味着代理将信息添加到队列的尾部,并将它们从头中删除。环队列是存放指定、固定消息数量的特殊队列。当新消息到达但队列已包含指定数量的消息时,代理通过删除队列头条来维护固定队列大小。
例如,假设配置了大小为 3
的环队列,以及按顺序发送消息 A
、B
、C
和 D
的生产者。当消息 C
到达队列时,队列中的消息数量已到达配置的环大小。此时,消息 A
位于队列的头部,而消息 C
则位于尾部。当消息 D
到达队列时,代理会将消息添加到队列的尾部。为保持固定队列大小,代理会删除队列的头部(即消息 A
)上的消息。Message 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>
default-ring-size
参数对于定义自动创建队列的默认大小特别有用。default-ring-size
的默认值为-1(
即无大小限制)。要在特定队列上定义环大小,请将
ring-size
键添加到queue
元素。指定一个值。例如:<addresses> <address name="myRing"> <anycast> <queue name="myRing" ring-size="5" /> </anycast> </address> </addresses>
您可以在代理运行时更新 ring-size
的值。代理会动态应用更新。如果新 ring-size
值低于前一个值,则代理不会立即从队列的头中删除信息来强制新大小。发送到队列的新消息仍强制删除旧消息,但队列不会达到新的、减小大小,直到客户端正常使用消息。
4.19.2. 环队列故障排除
本节描述了环队列的行为与其配置不同的情况。
交付消息和回滚
当消息传送给消费者时,该消息处于"不同"状态,其中邮件不再位于队列中,但尚未确认。消息会一直处于发送状态,直到消费者确认。处于非托管状态的消息无法从环队列中删除。
由于代理无法删除交付消息,客户端可以将更多消息发送到环队列,而不是环大小配置似乎允许。例如,考虑这种情况:
-
producer 将三个消息发送到配置了
ring-size="3"
的环队列。 所有消息会立即分配给消费者。
此时,Message
Count
=3
和 deliverCount
=3
。producer 将另一条消息发送到队列。然后,消息被分配到消费者。
现在,
messageCount
=4
和deliverCount
=4
。消息计数4
大于配置的环大小3
。但是,代理应该允许这种情况,因为它无法从队列中删除发送的消息。现在,假设使用者已经关闭,而不会导致任何消息。
在这种情况下,发送四个未确认的消息会取消相关的消息,并以相反的顺序重新添加到队列的头端。此操作将队列置于其配置的环大小。由于环队列优先于队列尾部的消息,因此队列丢弃由制作者发送的第一个消息,因为这是向队列头添加的最后一个消息。事务或者核心会话回滚的方式相同。
如果您直接使用核心客户端,或使用 AMQ Core Protocol JMS 客户端,您可以通过减少 consumerWindowSize
参数的值(默认为 1024 * 1024 字节)来最小化传输的消息数量。
调度的消息
当调度的消息发送到队列时,该消息不会立即添加到队列的尾部,如正常消息。相反,代理会在中间缓冲区中保存调度的消息,并根据消息的详细信息将消息调度到队列的头部。但是,调度的消息仍会反映在队列的消息数中。与收发消息一样,此行为可能会显示代理不强制实施环队列大小。例如,考虑这种情况:
at 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
会立即被删除。
页面信息
与在发送中调度的消息和消息类似,页面的消息不会计入代理强制的环队列大小,因为消息实际上是在地址级别页面,而不是队列级别。页面消息并非技术上在队列中,虽然它反映在队列的 messageCount
值中。
建议您不要对带有环队列的地址使用分页。相反,请确保整个地址可以容纳在内存中。或者,将 address-full-policy
参数配置为 DROP
, BLOCK
或 FAIL
。
其他资源
- 当您配置被动地址时,代理会创建环队列的内部实例。如需了解更多相关信息,请参阅 第 4.20 节 “配置被动地址”。