消息游标
消息游标
在早期版本的 ActiveMQ Classic 中,一个常见问题是使用非持久化消息时 内存缓冲区耗尽。
从 ActiveMQ Classic 5.0.0 开始,引入了一种新的内存模型,允许在有空间时从存储中分页读取消息(对于持久化消息使用存储游标)。
5.0 之前的版本在内存中保留了所有可分发到活动持久主题消费者或队列的消息的引用。虽然引用本身并不大,但它确实限制了可等待传递的消息的最大数量。
对于分发持久化消息的消息系统,一种典型的做法是当客户端准备消费时,使用游标来维护下一个分发位置,从长期存储中批量提取这些消息。这是一种稳健且可扩展性很高的方法,但对于消费者能够跟上消息生产者的场景来说,并非性能最佳。
ActiveMQ Classic 5.0 采用了一种混合方法,允许消息直接从生产者传递到消费者(在消息持久化后),但如果消费者落后,则切换回使用游标。
当消息消费者处于活动状态且速度很快时 - 能够跟上消息生产者
如果消费者在消息从存储中等待它时变为活动状态,或者它的速度比生产者慢,那么消息将从等待游标分页到分发队列。
游标类型
ActiveMQ Classic 5.0 中的默认消息游标类型是基于存储的。它表现如上所述。还有两种可以使用的游标类型:VM 游标和基于文件的游标,如下所述。
VM 游标
VM 游标是 ActiveMQ Classic 4.x 的工作方式:消息引用保存在内存中,并在需要时传递到分发队列。这速度很快,但也存在缺点,无法处理速度非常慢的消费者或长时间处于非活动状态的消费者:
基于文件的游标
基于文件的游标源自 VM 游标。当代理中的内存达到其限制时,它可以将消息分页到磁盘上的临时文件。当消息存储可能相对较慢但消费者通常速度很快时,可以使用这种类型的游标。通过缓冲到磁盘,它允许消息代理处理来自生产者的消息突发,而无需诉诸从慢速存储中分页读取。
非持久化消息的分页
基于存储的游标还处理非持久化消息的游标,这些消息未存储在消息存储中。非持久化消息直接传递到游标,因此基于存储的游标仅为这些类型的消息嵌入基于文件的游标。
配置游标
默认情况下,使用基于存储的游标,但可以根据目的地配置不同的游标。
主题订阅者
对于主题,每个订阅者都有一个分发队列和一个等待游标。可以为持久订阅者和瞬态订阅者配置不同的策略 - 例如
<destinationPolicy>
<policyMap>
<policyEntries>
<policyEntry topic="org.apache.>" producerFlowControl="false" memoryLimit="1mb">
<dispatchPolicy>
<strictOrderDispatchPolicy />
</dispatchPolicy>
<deadLetterStrategy>
<individualDeadLetterStrategy topicPrefix="Test.DLQ." />
</deadLetterStrategy>
<pendingSubscriberPolicy>
<vmCursor />
</pendingSubscriberPolicy>
<pendingDurableSubscriberPolicy>
<vmDurableCursor/>
</pendingDurableSubscriberPolicy>
</policyEntry>
</policyEntries>
</policyMap>
</destinationPolicy>
有效的订阅者类型是 vmCursor 和 fileCursor. 默认情况下是基于存储的游标。
有效的持久订阅者游标类型是 storeDurableSubscriberCursor、vmDurableCursor 和 fileDurableSubscriberCursor. 默认情况下是基于存储的游标。
队列
对于队列,每个目的地只有一个分发队列和一个等待队列,因此配置略有不同。
<destinationPolicy>
<policyMap>
<policyEntries>
<policyEntry queue="org.apache.>">
<deadLetterStrategy>
<individualDeadLetterStrategy queuePrefix="Test.DLQ."/>
</deadLetterStrategy>
<pendingQueuePolicy>
<vmQueueCursor />
</pendingQueuePolicy>
</policyEntry>
</policyEntries>
</policyMap>
</destinationPolicy>
有效的队列游标类型是 storeCursor、vmQueueCursor 和 fileQueueCursor. 默认情况下是基于存储的游标。