Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring boot 每x分钟从驼峰队列消费一次_Spring Boot_Apache Camel - Fatal编程技术网

Spring boot 每x分钟从驼峰队列消费一次

Spring boot 每x分钟从驼峰队列消费一次,spring-boot,apache-camel,Spring Boot,Apache Camel,试图实现一种方法,使我的消费者每隔30分钟左右从队列接收消息。 在上下文中,我的错误队列中有20条消息,直到x分钟过去,然后我的路由将使用队列中的所有消息并继续“睡眠”,直到另外30分钟过去 不确定实现这一点的最佳方式,我尝试了spring@Scheduled、camel timer等,但都没有达到我的期望。我一直在尝试让它与路由策略一起工作,但在正确的功能中没有骰子。它似乎会立即从队列中消耗掉 路由策略是正确的路径还是可以使用其他路径?从队列读取的路由将始终尽可能快地读取任何消息 您可以做的一

试图实现一种方法,使我的消费者每隔30分钟左右从队列接收消息。 在上下文中,我的错误队列中有20条消息,直到x分钟过去,然后我的路由将使用队列中的所有消息并继续“睡眠”,直到另外30分钟过去

不确定实现这一点的最佳方式,我尝试了spring@Scheduled、camel timer等,但都没有达到我的期望。我一直在尝试让它与路由策略一起工作,但在正确的功能中没有骰子。它似乎会立即从队列中消耗掉


路由策略是正确的路径还是可以使用其他路径?

从队列读取的路由将始终尽可能快地读取任何消息

您可以做的一件事是启动/停止或挂起使用消息的路由,因此进行以下设置:

route 1: error_q_reader, which goes from('jms').
route 2: a timed route that fires every 20 mins
管线2可以使用组件启动管线

 from('timer?20mins') // or whatever the timer syntax is...
    .to("controlbus:route?routeId=route1&action=start")
这里最棘手的部分是知道什么时候停止这条路线。你让它运行5分钟吗?消息全部用完后是否要停止?可能有一种方法可以运行另一个路由来检查队列深度(比如每1分钟左右),如果它为0,则关闭
路由1
,您可能会让它工作,但我可以向您保证,当您尝试处理大量异步操作时,这将变得混乱


您还可以尝试一些更奇特的方法,比如定制的
QueueBrowseStrategy
,它可以在队列上没有消息时触发事件关闭
route 1

从队列读取的路由将始终以尽可能快的速度读取任何消息

您可以做的一件事是启动/停止或挂起使用消息的路由,因此进行以下设置:

route 1: error_q_reader, which goes from('jms').
route 2: a timed route that fires every 20 mins
管线2可以使用组件启动管线

 from('timer?20mins') // or whatever the timer syntax is...
    .to("controlbus:route?routeId=route1&action=start")
这里最棘手的部分是知道什么时候停止这条路线。你让它运行5分钟吗?消息全部用完后是否要停止?可能有一种方法可以运行另一个路由来检查队列深度(比如每1分钟左右),如果它为0,则关闭
路由1
,您可能会让它工作,但我可以向您保证,当您尝试处理大量异步操作时,这将变得混乱


您还可以尝试一些更奇特的方法,比如定制的
QueueBrowseStrategy
,它可以在队列上没有消息时触发事件关闭
route 1

我构建了一个customer bean来清空队列并关闭,但这不是一个非常优雅的解决方案,我很想找到一个更好的解决方案

public class TriggeredPollingConsumer {

    private ConsumerTemplate consumer;
    private Endpoint consumerEndpoint;
    private String endpointUri;
    private ProducerTemplate producer;
    private static final Logger logger = Logger.getLogger( TriggeredPollingConsumer.class );

    public TriggeredPollingConsumer() {};

    public TriggeredPollingConsumer( ConsumerTemplate consumer, String endpoint, ProducerTemplate producer ) {
        this.consumer = consumer;
        this.endpointUri = endpoint;
        this.producer = producer;
    }

    public void setConsumer( ConsumerTemplate consumer) {
        this.consumer = consumer;
    }

    public void setProducer( ProducerTemplate producer ) {
        this.producer = producer;
    }

    public void setConsumerEndpoint( Endpoint endpoint ) {
        consumerEndpoint = endpoint;
    }

    public void pollConsumer() throws Exception {
        long count = 0;
        try {
            if ( consumerEndpoint == null ) consumerEndpoint = consumer.getCamelContext().getEndpoint( endpointUri );
            logger.debug( "Consuming: " + consumerEndpoint.getEndpointUri() );
            consumer.start();
            producer.start();
            while ( true ) {
                logger.trace("Awaiting message: " + ++count );
                Exchange exchange = consumer.receive( consumerEndpoint, 60000 );
                if ( exchange == null ) break;
                logger.trace("Processing message: " + count );
                producer.send( exchange );
                consumer.doneUoW( exchange );
                logger.trace("Processed message: " + count );
            }
            producer.stop();
            consumer.stop();
            logger.debug( "Consumed " + (count - 1) + " message" + ( count == 2 ? "." : "s." ) );
        } catch ( Throwable t ) {
            logger.error("Something went wrong!", t );
            throw t;
        }
    }

}
配置bean,然后从计时器调用bean方法,并配置直接路由来处理队列中的条目

from("timer:...")
  .beanRef("consumerBean", "pollConsumer");
from("direct:myRoute")
  .to(...);
然后,它将读取队列中的所有内容,并在一分钟内没有条目到达时立即停止。您可能希望缩短时间,但我发现,如果JMS速度有点慢,那么它将在排干队列的中途超时

from("timer:...")
  .beanRef("consumerBean", "pollConsumer");
from("direct:myRoute")
  .to(...);

我也一直在研究
sjms批处理组件,以及它如何与
pollEnrich
模式一起使用,但到目前为止,我还没能让它发挥作用。

我构建了一个客户bean来排出队列并关闭,但这不是一个非常优雅的解决方案,我很想找到一个更好的解决方案

public class TriggeredPollingConsumer {

    private ConsumerTemplate consumer;
    private Endpoint consumerEndpoint;
    private String endpointUri;
    private ProducerTemplate producer;
    private static final Logger logger = Logger.getLogger( TriggeredPollingConsumer.class );

    public TriggeredPollingConsumer() {};

    public TriggeredPollingConsumer( ConsumerTemplate consumer, String endpoint, ProducerTemplate producer ) {
        this.consumer = consumer;
        this.endpointUri = endpoint;
        this.producer = producer;
    }

    public void setConsumer( ConsumerTemplate consumer) {
        this.consumer = consumer;
    }

    public void setProducer( ProducerTemplate producer ) {
        this.producer = producer;
    }

    public void setConsumerEndpoint( Endpoint endpoint ) {
        consumerEndpoint = endpoint;
    }

    public void pollConsumer() throws Exception {
        long count = 0;
        try {
            if ( consumerEndpoint == null ) consumerEndpoint = consumer.getCamelContext().getEndpoint( endpointUri );
            logger.debug( "Consuming: " + consumerEndpoint.getEndpointUri() );
            consumer.start();
            producer.start();
            while ( true ) {
                logger.trace("Awaiting message: " + ++count );
                Exchange exchange = consumer.receive( consumerEndpoint, 60000 );
                if ( exchange == null ) break;
                logger.trace("Processing message: " + count );
                producer.send( exchange );
                consumer.doneUoW( exchange );
                logger.trace("Processed message: " + count );
            }
            producer.stop();
            consumer.stop();
            logger.debug( "Consumed " + (count - 1) + " message" + ( count == 2 ? "." : "s." ) );
        } catch ( Throwable t ) {
            logger.error("Something went wrong!", t );
            throw t;
        }
    }

}
配置bean,然后从计时器调用bean方法,并配置直接路由来处理队列中的条目

from("timer:...")
  .beanRef("consumerBean", "pollConsumer");
from("direct:myRoute")
  .to(...);
然后,它将读取队列中的所有内容,并在一分钟内没有条目到达时立即停止。您可能希望缩短时间,但我发现,如果JMS速度有点慢,那么它将在排干队列的中途超时

from("timer:...")
  .beanRef("consumerBean", "pollConsumer");
from("direct:myRoute")
  .to(...);

我也一直在研究
sjms批处理组件,以及如何将其与
pollEnrich
模式一起使用,但到目前为止,我还无法使其正常工作。

我已经解决了这一问题,通过在微服务方法中将我的应用程序用作CronJob,并赋予它优雅地自行关闭的能力,我们可以设置属性
camel.springboot.duration max idle seconds
。因此,您的JMS使用者路由保持简单

另一种方法是声明一个路由来控制JMS使用者路由的“生命周期”(开始、睡眠和恢复)


我强烈建议您使用第一种方法。

我已经解决了这个问题,通过将我的应用程序作为MicroServices方法中的CronJob,并赋予它优雅地关闭自身的能力,我们可以设置属性
camel.springboot.duration max idle seconds
。因此,您的JMS使用者路由保持简单

另一种方法是声明一个路由来控制JMS使用者路由的“生命周期”(开始、睡眠和恢复)

我强烈建议您使用第一种方法。

如果您使用,您可以利用它的优势

只需将JMS属性
AMQ\u SCHEDULED\u delay
设置为延迟的毫秒数,就可以延迟代理上的消息传递。骑骆驼很容易

.setHeader("AMQ_SCHEDULED_DELAY", 60000)
它并不完全是您想要的,因为它不会每30分钟清空一个队列,而是将每个消息延迟30分钟

请注意,您必须在代理配置中启用
schedulerSupport
。否则,将忽略延迟属性

<broker brokerName="localhost" dataDirectory="${activemq.data}" schedulerSupport="true">
...
</broker>

...
如果您使用它,您可以利用它的功能

只需将JMS属性
AMQ\u SCHEDULED\u delay
设置为延迟的毫秒数,就可以延迟代理上的消息传递。骑骆驼很容易

.setHeader("AMQ_SCHEDULED_DELAY", 60000)
它并不完全是您想要的,因为它不会每30分钟清空一个队列,而是将每个消息延迟30分钟

请注意,您必须在brok中启用
调度程序支持