Java Camel中消息的自动过期

Java Camel中消息的自动过期,java,activemq,apache-camel,Java,Activemq,Apache Camel,我有一个实现Camel和ActiveMQ的系统,用于在一些服务器之间进行通信。我想知道是否有一种方法可以在X段时间后自动过期并清除发送到队列的消息。因为原始服务器(填充队列)不知道是否有人在接收消息,所以我不希望我的队列一直增长,直到它太大以至于崩溃。奖励karma指向能够帮助并提供JavaDSL方法来实现此功能的人 解决方案 JMS为您提供了一种设置消息到期的机制。请看以下两个参考资料 :每封邮件 :每个目的地/每条消息 那么 SetJMSexPrivation(长期到期): 当你是客户时,

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

解决方案


JMS为您提供了一种设置消息到期的机制。请看以下两个参考资料

  • :每封邮件
  • :每个目的地/每条消息
  • 那么 SetJMSexPrivation(长期到期):

    当你是客户时,你不能打电话。请参阅我在ActiveMQ论坛上的演讲


    还要注意,客户机和代理之间的时钟需要同步,以便到期日正常工作。如果时钟不同步,则当代理收到消息时,客户端设置的到期日可能已经到期。或者客户机时间比代理提前,因此到期时间比10秒长


    我有点不明白为什么过期是基于客户端时间的。所以AMQ提供了一个插件,通过重新调整时间来解决这个问题,它只基于代理。请参见

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

    唯一要做的事情是创建一个名为setJMSExpiration.XML的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.DLQ队列,也可以提供特定的消息

    <policyEntry queue="MY.QUEUE.DLQ">
        <deadLetterStrategy>
            <sharedDeadLetterStrategy processExpired="false" />
        </deadLetterStrategy>
    </policyEntry>
    <policyEntry queue="ANOTHER.QUEUE">
        <deadLetterStrategy>
            <sharedDeadLetterStrategy processExpired="false" />
        </deadLetterStrategy>
    </policyEntry>
    
    
    
    这种方法的唯一限制是,您不能轻松地使用通配符,因为它是在这里编码的(您可以,但需要通过在驼峰路由中使用JMS目的地报头进行一些调整)


    我们试图让制作人定义timeToLive(并尽可能多地强制他们),但并不总是可以强制他们更改代码,这是为了尽量减少此类路由的数量。

    Endpoint optiontimeToLive()为我解决了所述问题,消息在300000毫秒后从队列中删除。 e、 g.“activemq:Q.QUEUE?disableReplyTo=true&timeToLive=300000”

    在我的例子中,设置头JMSExpiration并没有导致自动从队列中删除消息。
    但是这个医生给了我一个提示。

    看起来很有希望,我会在你在论坛上的留言中给它一个提示。它看起来好像你想要10分钟的过期时间,但却设置了10秒。比如(10*60*1000)对(10*1000)@Mondain不,我想要10秒。10分钟是从队列中清除过期消息的Qpid默认设置。例如:您向队列发送了一条过期设置为10秒的消息,因此在10秒后,该消息将通过QPid过期,任何使用者都无法使用该消息,但事实上,当删除策略线程启动时,该消息为delete bu QPid,默认设置为10分钟后启动OK,我误解了你在那里发布的内容。
    <!-- Add default Expiration (file in the same directory) -->
    <import resource="setJMSExpiration.xml"/>
    
    <policyEntry queue="MY.QUEUE.DLQ">
        <deadLetterStrategy>
            <sharedDeadLetterStrategy processExpired="false" />
        </deadLetterStrategy>
    </policyEntry>
    <policyEntry queue="ANOTHER.QUEUE">
        <deadLetterStrategy>
            <sharedDeadLetterStrategy processExpired="false" />
        </deadLetterStrategy>
    </policyEntry>