如何支持优先级队列
常见问题解答 > 使用 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,以避免更改您的客户端。这避免了在您的应用程序中使用选择器的需要,如上所示。