简体   繁体   English

一旦消息数量超过并发消费者数量,消费者就不会被分配给消息

[英]Consumer not getting allocated to message once the number of messages exceed number of concurrent consumers

I want to understand how the consumers work for concurrent consumer once a message is consumed.我想了解消费者在消费消息后如何为并发消费者工作。 Is the consumer bean discarded and new one created or is the consumer bean reused?是丢弃了消费者 bean 并创建了新的 bean,还是重新使用了消费者 bean? I can see after rabbit mq server is set up, when I send a message, a consumer bean is instantiated.可以看到rabbit mq server建立后,当我发送消息时,实例化了一个consumer bean。

My issue is that once the number of messages equals the number of concurrent consumers, the consumer in the message listener is null for the next message.我的问题是,一旦消息数量等于并发消费者的数量,则消息侦听器中的消费者对于下一条消息为空。 I can see the Ack/Nack for previous messages in my logs and the prefetch is set to 1.我可以在我的日志中看到先前消息的 Ack/Nack,并且预取设置为 1。

XML configuration : XML 配置:

<rabbit:admin connection-factory="cachingConnectionFactory" />

<rabbit:template id="template" connection-factory="cachingConnectionFactory"
    retry-template="retryTemplate" />

<!-- CachingConnectionFactory -->
<bean id="cachingConnectionFactory"
    class="org.springframework.amqp.rabbit.connection.CachingConnectionFactory">
    <constructor-arg ref="clientConnectionFactorySSL" />
    <property name="username" value="${QM_USERNAME}" />
    <property name="password" value="${QM_PASSWORD}" />
    <property name="virtualHost" value="${QM_VIRTUALHOST}" />
    <property name="host" value="${QM_HOST}" />
    <property name="port" value="${QM_PORT}" />
</bean>

<!-- SimpleRabbitListenerContainerFactory -->
        <bean id="rabbitListenerContainerFactory"
            class="org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory">
            <property name="connectionFactory">
                <ref bean="cachingConnectionFactory" />
            </property>
            <property name="concurrentConsumers" value="5" />
            <property name="maxConcurrentConsumers" value="8" />
             <property name="startConsumerMinInterval" value="3000" />
        </bean>

<!-- Message listener container -->
        <bean id="springListenerContainerRABC"          class="org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer">
            <property name="connectionFactory" ref="cachingConnectionFactory" />
            <property name="queues" ref="rabbitDestinationRABC" />
            <property name="messageListener" ref="rabbitMessageListenerRABC" />
            **<property name="concurrentConsumers" value="4" />**
            <property name="maxConcurrentConsumers" value="5" />
        </bean>

<!-- Message Listener -->
    <bean id="rabbitMessageListenerRABC" class="com.queue.rabbitmessaging.RabbitMQListener">
        **<property name="consumerType" value="XYZConsumer" />**
        <property name="responseSender" ref="XYZResponseSender" />
        <property name="taskExecutor" ref="taskExecutor" />
        <property name="encoding" value="UTF-16BE" />
    </bean>

<!-- Consumers -->
<bean id="XYZConsumer" class="com.msg.consumer.XYZConsumer"
    scope="prototype" />

Here is what I see in the logs :这是我在日志中看到的内容:

00:17:49.725 [springListenerContainerRABC-1] INFO RabbitMQListener - **Received message for consumer: XYZConsumer**

00:17:49.725 [springListenerContainerRABC-1] INFO RabbitMQListener - Message :: test1

00:17:49.725 [springListenerContainerRABC-1] INFO RabbitMQListener - Received message for consumer: XYZConsumer

00:17:49.725 [springListenerContainerRABC-1] INFO RabbitMQListener - Message :: test2

00:17:49.725 [springListenerContainerRABC-1] INFO RabbitMQListener - Received message for consumer: XYZConsumer

00:17:49.725 [springListenerContainerRABC-1] INFO RabbitMQListener - Message :: test3

00:17:49.725 [springListenerContainerRABC-1] INFO RabbitMQListener - Received message for consumer: XYZConsumer

00:17:49.725 [springListenerContainerRABC-1] INFO RabbitMQListener - Message :: test4

[org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#0-1] INFO RabbitMQListener - **Received message for consumer: null**

[org.springframework.amqp.rabbit.RabbitListenerEndpointContainer#0-1] INFO RabbitMQListener - Message :: test5

Consumer Code is as follows:消费者代码如下:

@EnableRabbit
@Service 
public class RabbitMQListener implements MessageListener {
    @Autowired
    private ApplicationContext applicationContext;

    protected static Logger logger = LoggerFactory.getLogger(RabbitMQListener.class);

    private TaskExecutor taskExecutor;
    private RabbitSender responseSender;
    private String consumerType;
    private String encoding;

     public TaskExecutor getTaskExecutor() {
        return taskExecutor;
    }

    public void setTaskExecutor(TaskExecutor taskExecutor) {
        this.taskExecutor = taskExecutor;
    }

    public void setResponseSender(RabbitSender responseSender) {
        this.responseSender = responseSender;
    }

    public void setConsumerType(String consumerType) {
        this.consumerType = consumerType;
    }

    public void setEncoding(String encoding) {
        this.encoding = encoding;
    }

    @Override
    @RabbitListener(containerFactory = Constants.CONTAINER_FACTORY, queues = "#{'${QM_QUEUES}'.split(',')}")
    public void onMessage(final Message arg0) {

        if (arg0 != null) {
            try {
                String message = new String(arg0.getBody());
                logger.info("Message Properties class: " + arg0.getClass());
                logger.info("Message Properties: " + arg0.getMessageProperties());
                logger.info("Received message for consumer: " + this.consumerType);
                logger.info("Message :: " + message);
                Object bean = applicationContext.getBean(this.consumerType);
                if (bean instanceof Consumer) {
                    logger.debug("Processing message for consumer: " + this.consumerType);
                    Consumer consumer = (Consumer)bean;
                    consumer.setMessage(message);
                    consumer.setResponseSender(responseSender);
                    logger.debug("Executing consumer: " + this.consumerType);
                    taskExecutor.execute(consumer);
                } else {
                    logger.info("Could not process message due to invalid consumer.");
                }

            } 
            catch (AmqpException e1) {
                logger.error("Spring AMQP error processing message.", e1.getMessage());
            }
            catch (Exception e2) {
                logger.error("General error processing message.", e2.getMessage());
            }
        }
        else {
            logger.debug("message received is NULL");
        }

    }


}

The described behavior is consistent with not acking messages after they are received.所描述的行为与在收到消息后不确认是一致的。 RabbitMQ can be configured to automatically acknowledge a message upon delivery. RabbitMQ 可以配置为在传递消息时自动确认消息。 If this does not happen, or is not configured, RabbitMQ will assume that the consumer is busy and will not deliver additional messages to it.如果这没有发生,或者没有配置,RabbitMQ 会假设消费者很忙,不会向它传递额外的消息。 You have to send an ack following the successful processing of a message to be able to receive the next message in the queue.您必须在成功处理消息后发送ack才能接收队列中的下一条消息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 当消息数大于并发使用者的数量时,如何消耗Spring IntegrationFlow中所需的所有消息? - How to consume all messages required in a Spring IntegrationFlow when message count is greater than the number of concurrent consumers? ActiveMQ:消费者一旦被选择处理特定的消息组,就不会收到非分组的消息 - ActiveMQ: consumer not getting non-grouped messages once it is selected to handle a specific message group Kafka 0.10.2消费者获得大量重复 - Kafka 0.10.2 consumers getting massive number of duplicates 行星超过数字框 - Planets exceed the Number Box Spring和RabbitMQ中并发消费者的消息接收顺序 - Order of message receiving with concurrent consumers in Spring and RabbitMQ 如何增加每批Spring Kafka Consumer消耗的消息数? - How to increase the number of messages consumed by Spring Kafka Consumer in each batch? 如何在ActiveMQ中与一个使用者一起使用N条消息 - How to consume N number of messages with one consumer in ActiveMQ 如何一次限制所有并发方法的线程数 - How to limit number of threads all concurrent methods at once 如何在 KAFKA 中停止并发消费者消费消息? - How to stop concurrent consumer consuming message in KAFKA? 使用 KafkaListener 一次从 Kafka 消费最少 N 条消息 - Consume minimum N number of messages once from Kafka with KafkaListener
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM