8

我正在开发一个由一些模块组成的应用程序。在其中一个模块中,有人创建了一个发布主题消息的主题生产者,但该模块没有主题消费者来使消息出列。主题生产者使用 .将 time-to-live 属性设置为 300000 毫秒setTimeToLive()

我希望如果没有消费者,消息会在 300000 毫秒内过期并被释放。

该应用程序部署在 Tomcat 6.0.36 上,它使用外部 ActiveMQ 服务器来处理队列和主题。

在主题设置下的 MBeans 选项卡中使用 Java VisualVM 监视 ActiveMQ 我看到变量“入队计数”增加了,但我不明白生存时间设置是否对这些消息生效。我预计会看到计数器“ExpiredCount”增加,但它仍然固定为 0。

有没有办法了解这些消息是否仍保留在内存中或是否已被释放?

非常感谢!

编辑:

我在 netbeans 7.3 上使用 j2ee 教程示例进行了一些测试,使用内部 glassfish 3.1 作为服务器,使用 jvisualvm 监控它,并且所有工作都如 api 所述:

JMS API 没有提供浏览主题的机制。消息通常一出现就从主题中消失:如果没有消息消费者来消费它们,JMS 提供者就会删除它们。尽管持久订阅允许消息在消息消费者不活动时保留在主题上,但不存在检查它们的工具。

我读到 glassfish 在 activeMQ 内部使用,所以我希望这对独立的 ActiveMQ 服务器也有效。

结束编辑。

4

1 回答 1

6

来自创建健壮的 JMS 应用程序的引用:

5.1.4 允许消息过期
[...]
当消息发布时,指定的timeToLive被添加到当前时间以给出过期时间。在指定的过期时间之前未传递的任何消息都将被销毁。

来源的另一句话javax.jms.Message#getJMSExpiration()

当到达消息的过期时间时,提供者应该丢弃它。[...]
客户端不应收到已过期的消息;但是,JMS API 不保证不会发生这种情况。

因此,如果是非持久订户:

  1. 服务器将消息发送给每个连接的订阅者。消息中的过期值设置为“当前时间 + TTL”。断开连接的订阅者将不会收到任何东西。
  2. 如果消息尚未过期,则连接的客户端正常接收消息。
  3. 如果连接的客户端在接收消息之前花费了太长时间(消息已过期),它可能会被服务器丢弃(可能在服务器尚未将其推送到客户端的缓冲区中)或者可以接收(可能在消息已经在客户端的缓冲区中)。

因此,在您的情况下,如果没有消费者,则消息可能根本不会存储。 队列计数增加,过期计数保持为 0。过期计数应仅在连接(但空闲)订户的情况下增加。

如何找到队列的大小

Enqueue Count - 自上次重启以来发送到队列的消息总数
Expired Count - 因为过期而未传递的消息数

注意:使用 JBoss 7 的测试表明,在这种情况下,消息不会出现在客户端中。

于 2013-08-29T11:01:19.200 回答