Wildfly JMS:当消息存在时,MDB bean空闲

我在Wildfly 8.1(HornetQ)上使用捆绑的JMS实现来OCR大量文档。

我希望有一个3个MDB池,消耗队列的消息和要被OCR的文件。 每个MDB都使用Apache commons-exec启动一个进程并阻塞,直到该进程退出。

在我的测试中,我有50条JMS消息(每条消息代表一个要被OCR的文档),它们在测试开始时加载到队列中。 处理开始时,在任何给定时间我都可以看到有3个CPU密集型OCR进程,一个由每个MDB启动和阻止。 在某些时候,在20分钟左右之后,其中一个OCR过程消失,并且在任何给定时间只有2个保持活着。 当剩余10条JMS消息时,另一个OCR进程停止,并且在任何给定时间只有1个。

最后,所有50个文档都已被OCR,并且任何OCR进程或我的应用程序都不会抛出任何exception。

我发现这种行为很奇怪,因为我希望在任何时间消耗JMS消息时都会有3个OCR进程处于活动状态(当然除外)。 如果在队列中输入时将JMS消息“分配”到MDB实例,而不是实时,则可以解释此行为。 例如,如果为每个MDB分配了大约17条消息。 根据文档大小,当其他MDB实例仍然可以使用消息时,某些MDB实例可以更早地完成并保持空闲而不消耗任何其他消息。

这是发生了什么? 如果是,是否有办法更改此设置,以便每当MDB实例完成处理消息时,都会向MDB实例分配消息?

@MessageDriven(activationConfig = { @ActivationConfigProperty(propertyName = "destinationLookup", propertyValue = "queue/csrOcrQueue"), @ActivationConfigProperty(propertyName = "minSession", propertyValue = "3"), @ActivationConfigProperty(propertyName = "maxSession", propertyValue = "3") }) @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) public class OcrMessageListener implements MessageListener { 

这与客户端(MDB)上的JMS消息缓冲有关。 默认情况下,将启用消息缓冲以避免网络延迟。 但是,对于我的客户速度慢的情况,这不是问题。

这来自HornetQ文档 :

39年1月11日。 没有消费者缓冲

默认情况下,HornetQ使用者在客户端实际接收它们之前,在客户端缓冲区中缓冲来自服务器的消息。 这提高了性能,因为否则每次调用receive()或处理MessageListener onMessage()方法中的最后一条消息时,HornetQ客户端都必须到服务器请求下一条消息,然后将其发送到客户端,如果有的话。

这将涉及每个消息的网络往返并降低性能。 因此,默认情况下,HornetQ会将消息预取到每个消费者的缓冲区中。

在某些情况下,缓冲是不可取的,HornetQ允许它被关闭。 这个例子certificate了这一点

作为文档的一部分,Github中有一个示例项目,其中关闭了消费者缓冲: 链接