【问题标题】:Auto expiration of messages in CamelCamel中的消息自动过期
【发布时间】:2012-01-15 16:25:04
【问题描述】:

我有一个实现 Camel 和 ActiveMQ 的系统,用于在一些服务器之间进行通信。我想知道是否有办法在 X 段时间后自动过期并清除发送到队列的消息。由于原始服务器(填充队列)不知道是否有人在接收消息,所以我不希望我的队列增长到太大以至于崩溃。 Bonus karma 指向可以提供帮助并提供 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);

【问题讨论】:

    标签: java activemq apache-camel


    【解决方案1】:

    JMS 为您提供了一种机制来设置消息的过期时间。看下面两个参考

    1. setJMSExpiration(long expiration):每条消息
    2. ActiveMQ: How do I set the message expiration:每个目标/每个消息

    【讨论】:

    • 看起来很有希望,我会试一试
    【解决方案2】:

    另外请注意,客户端 - 代理之间的时钟需要同步,才能使到期正常工作。如果时钟不同步,则从客户端设置的到期时间可能在代理接收到消息时已经到期。或者客户端时间早于代理,所以过期时间超过了 10 秒。

    为什么到期是基于客户端时间的,这让我有点吃惊。所以 AMQ 提供了一个插件,通过重新调整时间来解决这个问题,仅基于代理。见https://activemq.apache.org/timestampplugin.html

    【讨论】:

      【解决方案3】:

      在我们这边,我们选择使用部署在 ActiveMQ 服务本身中的骆驼路由来为特定目的地添加过期时间。

      唯一要做的就是创建一个如下所示的 XML 文件,其名称为 e.g. 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>
      

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

      我们尝试让生产者定义 timeToLive(并尽可能强制他们),但并不总是可以强制他们更改代码,这样可以最大限度地减少此类路由的数量。

      【讨论】:

        【解决方案4】:

        好吧 setJMSExpiration(长期过期):

        是您作为客户时不得调用的内容。请参阅我在 ActiveMQ 论坛上的讨论。

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

        【讨论】:

        • 在您在论坛上的消息中,您似乎想要 10 分钟到期,但设置为 10 秒。前任。 (10 * (60 * 1000)) 与 (10 * 1000)
        • @Mondain 不,我想要 10 秒。 10 分钟是从队列中清除过期消息的 Qpid 默认设置。例如:您向队列发送了一条消息,其过期时间设置为 10 秒,因此 10 秒后消息将被 QPid 过期,并且没有消费者可以使用它,但事实上该消息是在删除策略线程时删除 bu QPid( s) 启动,默认设置是 10 分钟后启动
        • 好的,我误解了您在此处发布的内容。
        【解决方案5】:

        端点选项 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 给了我一个提示。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-09-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-09-16
          • 2012-06-20
          相关资源
          最近更新 更多