如何支持优先级队列

 常见问题解答 > 使用 Apache ActiveMQ Classic > 如何支持优先级队列

如何支持优先级队列?

使用消息优先级

一个常见的需求是支持优先级消费,以便高优先级消息在低优先级消息之前被消费。

在 5.4 版本中,支持优先级队列。消息游标和消息存储(KahaDB 和 JDBC)都支持消息优先级。该支持默认情况下是禁用的,因此需要使用 目标特定策略 通过 XML 配置启用,在下面的示例中,“prioritizedMessages” 为所有队列启用。

<destinationPolicy>
  <policyMap>
    <policyEntries>
      <policyEntry queue=">" prioritizedMessages="true"/>
      ...

完整的优先级值范围 (0-9) 受 JDBC 消息存储支持。对于 KahaDB,支持三种优先级类别:低 (< 4)、默认 (= 4) 和高 (> 4)。

由于消息游标(和客户端)实现了优先级的严格排序,因此如果消息分发可以从缓存中发生,并且不必访问磁盘(即,您的消费者足够快以跟上生产者),或者如果您使用的是永远不必刷新到磁盘的非持久性消息(使用 FilePendingMessageCursor),则可以观察到严格的优先级排序。但是,一旦您遇到消费者速度慢或生产者速度明显快的情况,您就会观察到缓存将填满(可能包含低优先级消息),而高优先级消息将卡在磁盘上,直到它们被调入页面为止。在这种情况下,您可以决定在优化消息分发与优先级强制执行之间进行权衡。您可以禁用缓存、消息过期检查,并将您的消费者预取降低到 1,以确保从存储中获得高优先级消息,而不是低优先级消息。请注意,这种权衡可能会对性能造成重大影响,因此您必须彻底测试您的场景。

<destinationPolicy>
  <policyMap>
    <policyEntries>
      <policyEntry queue=">" prioritizedMessages="true" useCache="false" expireMessagesPeriod="0" queuePrefetch="1" />
      ...

替代策略

使用选择器

您可以让 100 个消费者使用选择器来查找高优先级的内容

JMSPriority > 6

然后让 50 个消费者处理平均或更高的优先级

JMSPriority >= 4

然后让 10 个消费者消费所有消息(因此所有优先级)。这样,您将始终有一个线程池处理高优先级消息,从而为您提供非常有效的基于优先级的消息分发,而无需 ActiveMQ Classic 在分发消息之前对消息进行批量处理和重新排序。

使用重排序器

您可以在某个输入队列 A 上对消息进行重新排序,并将它们按排序后的顺序发送到队列 B,以避免更改您的客户端。这避免了在您的应用程序中使用选择器的需要,如上所示。

为此,请使用 重排序器,它来自 企业集成模式

Apache、ActiveMQ、Apache ActiveMQ、Apache 羽毛徽标和 Apache ActiveMQ 项目徽标是 Apache 软件基金会的商标。版权所有 © 2024,Apache 软件基金会。根据 Apache 许可证 2.0 授权。