Camel中邮件的自动过期

时间:2012-01-15 16:25:04

标签: java activemq apache-camel

我有一个实现Camel和ActiveMQ的系统,用于某些服务器之间的通信。我想知道是否有一种方法可以在X时间段后自动过期并清除发送到队列的消息。由于始发服务器(填充队列)不知道是否有人正在接收消息,因此我不希望我的队列增长直到其大到崩溃。奖励业力指向可以帮助并提供java dsl方式来实现此功能的人。

解决方案

// expire message after 2 minutes
long ttl = System.currentTimeMillis() + 120000;
// send our info one-way to the group topic
camelTemplate.sendBodyAndHeader("jms:queue:stats", ExchangePattern.InOnly, stats, "JMSExpiration", ttl);

5 个答案:

答案 0 :(得分:6)

JMS提供了一种机制,可以设置消息的到期日期。请看以下两个参考文献

  1. setJMSExpiration(long expiration):每封邮件
  2. ActiveMQ: How do I set the message expiration:per destionation / per message

答案 1 :(得分:3)

还要注意客户端 - 代理之间的时钟需要同步,以使到期工作正常。如果时钟不同步,则当在代理上接收到消息时,从客户端设置的到期时间可能已经过期。或者客户时间早于经纪人,因此到期时间超过10秒。

它有点打败了我为什么到期是基于客户时间。所以AMQ提供了一个插件,通过重新调整时间来解决这个问题,只能基于经纪人。见https://activemq.apache.org/timestampplugin.html

答案 2 :(得分:1)

好吧     setJMSExpiration(long expiration):

当你是客户时,

是你不能打电话的东西。在ActiveMQ论坛上看到我对此的一些看法。

https://apache-qpid-developers.2158895.n2.nabble.com/MRG-Java-JMS-Expiration-td7171854.html

答案 3 :(得分:1)

在我们这边,我们选择使用部署在ActiveMQ服务中的驼峰路线将到期时间添加到特定目的地。

唯一要做的就是使用以下名称创建如下所示的XML文件: setJMSExpiration.xml

<beans xmlns="http://www.springframework.org/schema/beans"  
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="
     http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

  <camelContext id="camel-set-expiration" xmlns="http://camel.apache.org/schema/spring">
    <!-- Copy route for each destination to expire -->
    <route id="setJMSExpiration.my.queue.dlq">
      <from uri="broker:queue:MY.QUEUE.DLQ"/>
        <setHeader headerName="JMSExpiration">
          <!-- Message will expire after 1 day -->
          <spel>#{T(java.lang.System).currentTimeMillis() + 86400000}</spel>
        </setHeader>
      <to uri="broker:queue:MY.QUEUE.DLQ"/>
    </route>
    <route id="setJMSExpiration.another.queue">
      <from uri="broker:queue:ANOTHER.QUEUE"/>
        <setHeader headerName="JMSExpiration">
          <!-- Message will expire after 5 days -->
          <spel>#{T(java.lang.System).currentTimeMillis() + 432000000}</spel>
        </setHeader>
      <to uri="broker:queue:ANOTHER.QUEUE"/>
    </route>
  </camelContext>
</beans>

并将其导入您的activemq.xml配置中:

<!-- Add default Expiration (file in the same directory) -->
<import resource="setJMSExpiration.xml"/>

如果您不希望过期的消息到达ActiveMQ.DLQ队列,您也可以提供特定的per destination policies

<policyEntry queue="MY.QUEUE.DLQ">
    <deadLetterStrategy>
        <sharedDeadLetterStrategy processExpired="false" />
    </deadLetterStrategy>
</policyEntry>
<policyEntry queue="ANOTHER.QUEUE">
    <deadLetterStrategy>
        <sharedDeadLetterStrategy processExpired="false" />
    </deadLetterStrategy>
</policyEntry>

这种方式的唯一限制是你不能轻易使用通配符,因为它在这里编码(你可以,但它需要通过在camel路由中使用JMS目标头进行一些调整)。

我们试图让生产者定义timeToLive(并尽可能强制它们),但并不总是强迫他们改变他们的代码,这样可以最大限度地减少这些路径的数量。

答案 4 :(得分:0)

端点选项 timeToLive http://camel.apache.org/jms.html)为我解决了上述问题,在300000毫秒后将消息从队列中删除。 例如“ activemq:Q.QUEUE?disableReplyTo = true& timeToLive = 300000”

设置标头JMSExpiration,在我的情况下,不会导致自动从队列中删除消息。 但这文档https://www.ibm.com/support/knowledgecenter/en/SSAW57_9.0.0/com.ibm.websphere.nd.multiplatform.doc/ae/rwsf_prjms_timetolive.html给了我一个提示。