骆驼rabbitmq中重启时的骆驼路线丢失消息

时间:2020-04-04 16:10:35

标签: rabbitmq apache-camel rabbitmq-exchange

我正在使用camel-rabbitmq。 这是我的路线定义

camelContext.addRoutes(new RouteBuilder() {
        @Override
        public void configure() throws Exception {
            from("rabbitmq:TEST?queue=TEST&concurrentConsumers=5")
            .routeId("jms")
            .autoStartup(false)
            .throttle(10)
            .asyncDelayed()
            .log("Consuming message ${body} to ${header.deliveryAddress}")
            .process(new Processor() {

                @Override
                public void process(Exchange exchange) throws Exception {
                        System.out.println(atomicLong.decrementAndGet());
                }
            })

            ;
        }
    }); 

当我将500条消息推送到此队列时,在停止和开始路由时,通道上的所有消息都将丢失,无论它们去向何方。

如果我使用&autoAck=false配置了相同的路由,则它可以正常工作,但会降低性能。为什么骆驼在不使用autoAck和不使用autoAck的情况下都无法提供相同的行为。

2 个答案:

答案 0 :(得分:0)

我改变了骆驼兔mq的rabbitmq消费方式,从而解决了我的问题

    public void handleCancelOk(String consumerTag) {
        // no work to do
        log.info("Received cancelOk signal on the rabbitMQ channel");
        **downLatch.countDown();**
    }
  @Override
    protected void doStop() throws Exception {
        if (channel == null) {
            return;
        }
        this.requeueChannel=openChannel(consumer.getConnection());
         if (tag != null && isChannelOpen()) {
            channel.basicCancel(tag);
        }
        stopping=true;
         downLatch.await();         

        try {
            lock.acquire();
            if (isChannelOpen()) {
                channel.close();
            }
        } catch (TimeoutException e) {
            log.error("Timeout occured");
            throw e;
        } catch (InterruptedException e1) {
            log.error("Thread Interrupted!");
        } finally {
            lock.release();
        }


    }

通过执行此骆驼路线,消息将被消耗,并避免了消息丢失。

答案 1 :(得分:0)

您需要检查Rabbitmq消费者预取计数 consumer prefetch 我认为默认情况下,使用者会选择队列中的所有消息到其内存缓冲区。 如果将预取计数设置为1,使用者将一一确认消息。 所有其他未确认的消息将以就绪状态出现在队列中。在使用者完成对上一条收到的邮件的任务之后,等待收件。