Java JMS 主题生存时间

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18507595/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 08:39:24  来源:igfitidea点击:

JMS topic time to live

javatomcatwebjmsactivemq

提问by Stefania

I'm working on an application consisting of some modules. In one of those module someone created a topic producer that publishes messages on a topic, but this module hasn't a topic consumer to dequeue the messages. The topic producer sets the time-to-live property to 300000 milliseconds using setTimeToLive().

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

I expect that if there is no consumer, the messages expire within 300000 milliseconds and they are deallocated.

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

The application is deployed on Tomcat 6.0.36 and it uses an external ActiveMQ server to handle the queues and topics.

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

Monitoring ActiveMQ with Java VisualVM in the MBeans tab under the topic settings I see that the variable "Enqueue Count" grows, but I don't understand if the time-to-live settings took effect on these messages. I expected to see the counter "ExpiredCount" to increase, but it still remains fixed to 0.

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

Is there a way to understand if those messages still stay in memory or if they are deallocated?

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

Thank you very much!

非常感谢!

EDIT:

编辑:

I did some tests using j2ee tutorial examples on netbeans 7.3 using internal glassfish 3.1 as server, monitoring it with jvisualvm and all works as api says:

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

The JMS API provides no mechanism for browsing a topic. Messages usually disappear from a topic as soon as they appear: if there are no message consumers to consume them, the JMS provider removes them. Although durable subscriptions allow messages to remain on a topic > while the message consumer is not active, no facility exists for examining them.

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

I read that glassfish uses inside activeMQ so I hope that this is valid also for a standalone ActiveMQ server.

我读到 glassfish 在 activeMQ 中使用,所以我希望这也适用于独立的 ActiveMQ 服务器。

END EDIT.

结束编辑。

回答by Beryllium

A quote from Creating Robust JMS Applications:

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

5.1.4 Allowing Messages to Expire
[...]
When the message is published, the specified timeToLiveis added to the current time to give the expiration time. Any message not delivered before the specified expiration time is destroyed.

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

Another quote from the source of javax.jms.Message#getJMSExpiration():

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

When a message's expiration time is reached, a providershould discardit. [...]
Clientsshould not receive messages that have expired; however, the JMS API does not guaranteethat this will not happen.

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

So in case of non durable subscribers:

因此,对于非持久订阅者:

  1. The server sends the message to each connected subscriber. The expiry value in the message is set to "current time + TTL". Disconnected subscribers will not receive anything.
  2. A connected client receives the message normally, if it has not yet expired.
  3. If a connected client takes too long before receiving a message (the message has expired), it might be discarded by the server (possibly in case the server has not yet pushed it into the client's buffer) or it can be received (possibly in case the message is already in the client's buffer).
  1. 服务器将消息发送给每个连接的订阅者。消息中的到期值设置为“当前时间+ TTL”。断开连接的订阅者将不会收到任何东西。
  2. 如果消息尚未过期,已连接的客户端会正常接收消息。
  3. 如果连接的客户端在接收消息之前花费的时间太长(消息已过期),则它可能会被服务器丢弃(可能是因为服务器尚未将其推送到客户端的缓冲区中)或者可以接收到(可能是以防万一)消息已经在客户端的缓冲区中)。

So in your case, if there is no consumer, the message is probably not stored at all. Enqueue countis increased, and Expired Countremains at 0. Expired countshould only increase in case of a connected (but idle) subscriber.

所以在你的情况下,如果没有消费者,消息可能根本没有存储。 入队计数增加,过期计数保持为 0。过期计数只应在连接(但空闲)订阅者的情况下增加。

A quote from How do I find the Size of a Queue

引自如何找到队列的大小

Enqueue Count - the total number of messages sent to the queue since the last restart
Expired Count - the number of messages that were not delivered because they were expired

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

Note: A test using JBoss 7 shows that in this case the message does not turn up in the client.

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