4.19. 配置环队列


通常,AMQ Broker 中的队列使用第一个、第一个(FIFO)语义。这意味着代理将消息添加到队列的末尾,并将它们从头中删除。环环队列是一种特殊的队列类型,其中包含指定的、固定消息的数量。当新消息到达但队列包含指定数量的消息时,代理通过删除队列头的消息来维护固定队列大小。

例如,假设配置了大小为 3 的环队列,以及按顺序发送消息 ABCD 的制作者。消息 C 到达队列后,队列中的消息数量就达到配置的环大小。此时,消息 A 位于队列的头,而消息 C 则位于尾部。当消息 D 到达队列时,代理会将消息添加到队列的尾部。为了保持固定队列大小,代理会在队列头删除消息(即消息 A)。消息 B 现在位于队列的头。

4.19.1. 配置环队列

以下流程演示了如何配置环队列。

流程

  1. 打开 & lt;broker_instance_dir> /etc/broker.xml 配置文件。
  2. 要在未设置显式环大小的匹配地址上定义默认环大小,请在 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 (即没有大小限制)。

  3. 要在特定队列上定义环环大小,请将 ring-size 密钥添加到 queue 元素中。指定一个值。例如:

    <addresses>
       <address name="myRing">
          <anycast>
             <queue name="myRing" ring-size="5" />
          </anycast>
       </address>
    </addresses>
注意

您可以在代理运行时更新 ring-size 的值。代理会动态应用更新。如果新 ring-size 值低于先前值,代理不会立即从队列头删除消息来强制实施新大小。发送到队列的新消息仍会强制删除旧消息,但队列不会达到新的、缩小的大小,直到客户端通过正常消耗消息为止。

4.19.2. 对环队列进行故障排除

这部分论述了环队列的行为与其配置不同的情况。

发送消息和回滚

当消息发送到消费者时,消息处于"in-between"状态,其中消息不再在队列中,但还没有确认。在被消费者确认之前,消息会一直处于 in-delivery 状态。处于 in-delivery 状态的消息无法从环队列中删除。

由于代理无法删除 in-delivery 消息,因此客户端可以将比环队列所允许的更多消息发送到环队列。例如,请考虑这种情况:

  1. 生产者向配置了 ring-size="3" 的环队列发送三个消息。
  2. 所有消息都会立即分配给消费者。

    At this point, messageCount= 3 and deliveringCount= 3.

  3. 生产者向队列发送另一个消息。然后,消息会被分配给消费者。

    现在,messageCount = 4deliveryCount = 4。消息数为 4 大于配置的环大小 3。但是,代理被认为是允许这种情况,因为它无法从队列中删除消息。

  4. 现在,假设消费者在不确认任何消息的情况下关闭。

    在这种情况下,四个 in-delivery,未确认的消息将取消回代理,并根据它们使用的相反顺序添加到队列的标头中。此操作会使队列置于其配置的环大小上。由于环队列首选通过头的消息在队列的尾部消息,因此队列丢弃生成者发送的第一个消息,因为这是最后一个消息,将添加回队列头。事务或核心会话回滚的方式相同。

如果您直接使用核心客户端,或使用 AMQ Core Protocol JMS 客户端,您可以通过减少 consumerWindowSize 参数的值(默认为 1024 * 1024 字节)来最小化传输的消息数量。

调度的消息

当调度的消息发送到队列时,消息不会立即添加到队列的尾部,如普通消息。相反,代理将调度的消息保存在中间缓冲区中,并根据消息的详细信息将消息发送到队列头。但是,调度的消息仍然反映在队列的消息数中。与 in-delivery 消息一样,此行为可能会使其显示代理没有强制实施环队列大小。例如,请考虑这种情况:

  1. 在 12:00 时,生产者将消息 A 发送到配置了 ring-size="3" 的环队列。该消息调度到 12:05。

    此时,messageCount= 1scheduledCount= 1

  2. 在 12:01 中,生成者将消息 B 发送到同一环队列。

    现在,messageCount= 2scheduledCount= 1

  3. 在 12:02 中,生成者将消息 C 发送到同一环队列。

    现在,messageCount= 3scheduledCount= 1

  4. 在 12:03 时,生成者将消息 D 发送到同一环队列。

    现在,messageCount= 4scheduledCount= 1

    队列的消息数现在是 4一个大于 配置的环大小为 3。但是,调度的消息还没有在队列中(即,它位于代理中,并计划放置到队列中)。在 12:05 调度的发送时,代理会将消息放置在队列的标头中。但是,由于环队列已达到其配置的大小,因此调度的消息 A 会立即被删除。

页面的信息

与发送中调度的消息和消息类似,页的消息不会计算到代理强制的环队列大小,因为消息实际上是在地址级别进行分页,而不是队列级别。页面的消息不是技术在队列中,尽管它反映在队列的 messageCount 值中。

建议您不要将分页用于带环队列的地址。相反,请确保整个地址可以容纳内存。或者,将 address-full-policy 参数配置为 DROP, BLOCKFAIL

其他资源

Red Hat logoGithubRedditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

© 2024 Red Hat, Inc.