【问题标题】:Reading messages from rabbitMQ queue at an interval is not working每隔一段时间从rabbitMQ队列中读取消息不起作用
【发布时间】:2021-09-27 06:01:16
【问题描述】:

我想要实现的是每 15 分钟从 RabbitMQ 队列中读取一次消息。从文档中,我可以看到我可以使用“receiveTimeout”方法来设置间隔。

轮询消费者

AmqpTemplate 本身可用于轮询消息接收。默认情况下,如果没有消息 可用,null 立即返回。没有阻塞。从 1.5 版本开始,您可以设置 一个receiveTimeout,以毫秒为单位,并且接收方法会阻塞很长时间,等待一个 消息。

但我尝试通过 sprint 集成来实现它,receiveTimeout 没有按预期工作。

我的测试代码如下。

@Bean
    Queue createMessageQueue() {
        return new Queue(RetryQueue, false);
    }

    @Bean
    public SimpleMessageListenerContainer QueueMessageListenerContainer(ConnectionFactory connectionFactory) {
        final SimpleMessageListenerContainer messageListenerContainer = new SimpleMessageListenerContainer(
                connectionFactory);
        messageListenerContainer.setQueueNames(RetryQueue);
        messageListenerContainer.setReceiveTimeout(900000);
        return messageListenerContainer;
    }

    @Bean
    public AmqpInboundChannelAdapter inboundQueueChannelAdapter(
            @Qualifier("QueueMessageListenerContainer") AbstractMessageListenerContainer messageListenerContainer) {
        final AmqpInboundChannelAdapter amqpInboundChannelAdapter = new AmqpInboundChannelAdapter(
                messageListenerContainer);
        amqpInboundChannelAdapter.setOutputChannelName("channelRequestFromQueue");
        return amqpInboundChannelAdapter;
    }

    @ServiceActivator(inputChannel = "channelRequestFromQueue")
    public void activatorRequestFromQueue(Message<String> message) {
        System.out.println("Message: " + message.getPayload() + ", recieved at: " + LocalDateTime.now());
    }

我正在近乎实时地将有效负载记录在控制台中。 任何人都可以帮忙吗?消费者一旦开始活跃多久?

更新

IntegrationFlow 我曾经每隔一段时间从队列中检索消息,

@Bean
    public IntegrationFlow inboundIntegrationFlowPaymentRetry() {
        return IntegrationFlows
                .from(Amqp.inboundPolledAdapter(connectionFactory, RetryQueue),
                        e -> e.poller(Pollers.fixedDelay(20_000).maxMessagesPerPoll(-1)).autoStartup(true))
                .handle(message -> {
                    channelRequestFromQueue()
                            .send(MessageBuilder.withPayload(message.getPayload()).copyHeaders(message.getHeaders())
                                    .setHeader(IntegrationConstants.QUEUED_MESSAGE, message).build());
                }).get();
    }

【问题讨论】:

    标签: rabbitmq spring-integration spring-amqp


    【解决方案1】:

    Polling Consumer 文档来自关于 `RabbitTemplate 的 Spring AMQP 文档,与侦听器容器或 Spring 集成无关。

    https://docs.spring.io/spring-amqp/docs/current/reference/html/#polling-consumer

    Spring 集成的适配器是消息驱动的,只要消息可用,您就会收到消息。

    要按需获取消息,您需要在任何时间间隔拨打RabbitTemplate

    【讨论】:

    • 如果你已经在 Spring Integration 中也可以使用它:docs.spring.io/spring-integration/docs/current/reference/html/…
    • @ArtemBilan 谢谢。我一直在寻找这样的东西。但是当我尝试时,会在指定的时间间隔内获取单个消息。但我需要的是,我想在轮询队列时获取所有可用的消息。你能给我一个提示吗?
    • 在轮询器上设置maxMessagesPerPoll;它默认为 1,-1 表示继续获取,直到没有更多。 Pollers.fixedDelay(1_000).maxMessagesPerPoll(-1).
    • 请注意,如果您想避免丢失消息丢失,您应该使用事务轮询器;默认情况下,消息在获取后被确认。
    • @GaryRussell 如果某些情况,我需要发布已经获取的消息。我使用了 StaticMessageHeaderAccessor.getAcknowledgementCallback(queuedMessage).acknowledge(Status.REQUEUE);重新排队消息。但这里的问题是,重新排队的消息会立即被轮询器拾取。因此它进入了一个无限循环。你能给些建议么?问题中添加了poller代码sn-p供大家参考。
    猜你喜欢
    • 2023-03-09
    • 2019-11-21
    • 1970-01-01
    • 2017-09-16
    • 2013-12-18
    • 2013-08-09
    • 2011-01-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多