RabbitMQ通道空闲问题|如何恢复未确认的AMQP消息| Javaclient使用者

RabbitMQ通道空闲问题|如何恢复未确认的AMQP消息| Javaclient使用者,rabbitmq,spring-amqp,spring-rabbit,Rabbitmq,Spring Amqp,Spring Rabbit,我是rabbitmq的消费者,使用spring amqp。现在,当我进入admin时,所有连接都显示为正在运行,但其中的通道都处于空闲状态(预回迁:250,未确认:250)。你能帮忙吗? 如何正确使用此预取? 我需要关闭连接吗? 如何增加每个连接的通道数。目前,每个连接只有一个通道。下面是代码配置片段。我正在使用out-if-box-spring amqp配置来处理大多数事情。我还使用自定义rabbitmq消息侦听器来确认或取消确认消息 <!-- RabbitMQ configuratio

我是rabbitmq的消费者,使用spring amqp。现在,当我进入admin时,所有连接都显示为正在运行,但其中的通道都处于空闲状态(预回迁:250,未确认:250)。你能帮忙吗? 如何正确使用此预取? 我需要关闭连接吗? 如何增加每个连接的通道数。目前,每个连接只有一个通道。下面是代码配置片段。我正在使用out-if-box-spring amqp配置来处理大多数事情。我还使用自定义rabbitmq消息侦听器来确认或取消确认消息

<!-- RabbitMQ configuration -->
    <rabbit:connection-factory id="connectionFactory" host="${rabbitmq.host}" port="${rabbitmq.port}" username="${rabbitmq.username}" password="${rabbitmq.password}" virtual-host="${rabbitmq.vhosts}" requested-heartbeat="${rabbitmq.requestedHeartBeat}"/>

    <rabbit:template id="rabbitTemplate" connection-factory="connectionFactory" message-converter="rabbitJsonConverter"/>
    channel.Close
    <bean id="rabbitJsonConverter" class="rabbitmq.messages.converter.CustomJackson2JsonMessageConverter">
        <property name="classMapper">
            <bean class="org.springframework.amqp.support.converter.DefaultClassMapper">
                <property name="defaultType" value="rabbitmq.messages.custom.dto.CustomRabbitMQMessage"/>
            </bean>
        </property>
    </bean>

    <rabbit:listener-container connection-factory="connectionFactory" acknowledge="manual" requeue-rejected="true">
        <rabbit:listener queue-names="${rabbitmq.queuename}" ref="customRabbitMQMessageListener" method="onMessage"/>
    </rabbit:listener-container>

<bean id="customRabbitMQMessageListener" class="rabbitmq.messages.listener.CustomRabbitMQMessageListener" >
        <property name="customerAccountService" ref="customerAccountService" />
    </bean>


因此,这个问题的解决方案是在为手动确认配置的侦听器代码中。逻辑中有一些分支使侦听器无法确认某些消息,这就是通道上未确认的计数达到预取(250)的原因,使RabbitMQ停止向通道发送消息

修正:正如您在问题中看到的更新的侦听器代码一样,它从不留下任何未确认的消息。
同样在否定确认通道中.basicNack(msg.getMessageProperties().getDeliveryTag(),false,true),requeue(签名中的最后一个变量)应为true,以便可以将消息重新查询回同一队列

请显示
CustomRabbitMQMessageListener
的代码。它有什么作用?你真的调用了
channel.basicAck()
?你没有描述问题-这些数字只是意味着每个消费者有250条未处理的消息。如果您没有看到进展,则表示您无法确认或nack这些消息。代理只允许预取未确认的消息。这里的单词
idle
没有任何意义-您必须询问RabbitMQ工程师它是什么意思(RabbitMQ用户Google组)。现在还不清楚“每个连接一个频道”是什么意思。如您所见,每个使用者都有自己的通道。@ArtemBilan:是的,我在CustomRabbitMQMessageListener中所做的是,如果我成功地对消息执行了所需的操作,那么我将执行channel.basicAck(),如果我得到内部异常或由于某些限制,我希望稍后再次处理该消息,然后我发送channel.basicNack()@GaryRussell-如果我未能确认这些消息,并且它们已达到预回迁等于未确认消息的计数,我应该在此处执行什么操作来确认或nack这些消息。因为rabbimq一旦h=unack就停止向通道发送消息。rabbitmq的官方消息还说:@GaryRussell,Artem:顺便说一句,修复侦听器是有效的。现在,队列已完全消耗,并且是空的。我会更新答案。请接受。谢谢大家的建议:)
**Listener Code**
LOG.debug("***** LISTENING RABBITMQ MESSAGES START******");
        channel.basicRecover(true);
        try {
                boolean ack = performOperationsOnMessage(msg);
                if (ack) {
                    channel.basicAck(msg.getMessageProperties().getDeliveryTag(), false);
                } else
                    channel.basicNack(msg.getMessageProperties().getDeliveryTag(), false, true);
                LOG.debug("***** LISTENING RABBITMQ MESSAGES FINISHED******");
        } catch (Exception exp) {
            LOG.error("Exception occured during perform Change operation, RabbitMQ message: " + exp.getMessage(), exp);
            channel.basicNack(msg.getMessageProperties().getDeliveryTag(), false, true);
        }

private boolean performOperationsOnMessage(Message msg) {
        RabbitMQMessage message = null;
            try {
                message = (RabbitMQMessage) rabbitJsonConverter.fromMessage(msg);
            } catch (MessageConversionException exp) {
                LOG.warn("Exception occurred during the conversion or any other issue", exp);
                return true;
            }
        if (message == null || message.getOperation() == null || message.getResource() == null || message.getResource().getUuid() == null) {
            LOG.warn("Received an empty message  or emptry operation or empty resource or empty uuid from queue ");
            return true;
        }
        if (message.getOperation().equals(RabbitMQMessage.RossoOperation.remove.name())) {
            return performRemoveOperation(message);
        }
        if (message.getOperation().equals(RabbitMQMessage.RossoOperation.change.name())) {
            return performChangeOperation(message);
        }
        return true;
    }