Как записать имя очереди в SimpleMessageListenerContainer.java

У нас возникли проблемы с одним из потребителей, и нам нужно отладить код. SimpleRabbitListenerContainerFactory позволяет установить ConsumerTagStrategy, который должен добавлять теги во время ведения журнала.

@Bean
public SimpleRabbitListenerContainerFactory analyzeTransactionListenerContainerFactory(ConnectionFactory connectionFactory, AsyncTaskExecutor asyncTaskExecutor) {
    connectionFactory.getVirtualHost());
    SimpleRabbitListenerContainerFactory factory = new  SimpleRabbitListenerContainerFactory();
    factory.setConnectionFactory(connectionFactory);
    factory.setConcurrentConsumers(2);
    factory.setMaxConcurrentConsumers(4);
    factory.setTaskExecutor(asyncTaskExecutor);
    ConsumerTagStrategy consumerTagStrategy = new ConsumerTagStrategy() {
        @Override
        public String createConsumerTag(String queue) {
            return queue;
        }
     };
     factory.setConsumerTagStrategy(consumerTagStrategy);
     return factory;
}

Тем не менее, журналы по-прежнему не имеют тега. Таким образом, невозможно найти, для какой очереди/потребителя предназначено это сообщение.

LogLevel=DEBUG; category=org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer; msg=Cancelling Consumer: tags=[{}], channel=Cached Rabbit Channel: AMQChannel(amqp://[email protected]:5672/,47), acknowledgeMode=AUTO local queue size=0; 

LogLevel=DEBUG; category=org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer; msg=Idle consumer terminating: Consumer: tags=[{}], channel=Cached Rabbit Channel: AMQChannel(amqp://[email protected]:5672/,47), acknowledgeMode=AUTO local queue size=0; 

Как добавить некоторые теги в журнал SimpleMessageListenerContainer?


person nsdiv    schedule 23.02.2016    source источник


Ответы (1)


Что ж, похоже, вы немного неправильно поняли Consumer Key. Из документов RabbitMQ:

потребительская метка потребительская метка

Задает идентификатор потребителя. Тег потребителя является локальным для канала, поэтому два клиента могут использовать одни и те же теги потребителя. Если это поле пусто, сервер сгенерирует уникальный тег.

Клиент НЕ ДОЛЖЕН указывать тег, который относится к существующему потребителю. Код ошибки: не разрешено

Тег потребителя действителен только в пределах канала, из которого был создан потребитель. т.е. клиент НЕ ДОЛЖЕН создавать потребителя в одном канале, а затем использовать его в другом. Код ошибки: не разрешено

SimpleMessageListenerContainer заполняет свою внутреннюю карту для ConsumerTags, когда начинает прослушивать предоставленные очереди. Если мы слушаем (потребляем) там, мы можем увидеть их из:

public String toString() {
    return "Consumer: tags=[" + (this.consumerTags.toString()) + "], channel=" + channel
            + ", acknowledgeMode=" + acknowledgeMode + " local queue size=" + queue.size();
}

как вы ожидаете, конечно.

Но если мы больше не потребляем, например, в случае Channel#basicCancel.

Или... просматривая ваше второе сообщение журнала во время простоя. Когда у вас есть лишний Потребитель, но для него нет сообщения.

Код по этому вопросу выглядит так:

boolean receivedOk = receiveAndExecute(this.consumer); // At least one message received
if (SimpleMessageListenerContainer.this.maxConcurrentConsumers != null) {
    if (receivedOk) {
.....
    }
    else {
        consecutiveMessages = 0;
        if (consecutiveIdles++ > SimpleMessageListenerContainer.this.consecutiveIdleTrigger) {
            considerStoppingAConsumer(this.consumer);
            consecutiveIdles = 0;
        }
   }
}

Так что, возможно, вы зря беспокоитесь. И вы видите журналы только для этих дополнительных потребителей. Для этого случая у вас есть maxConcurrentConsumers > concurrentConsumers.

person Artem Bilan    schedule 23.02.2016
comment
Так вы говорите, что когда потребитель простаивает, тегов не будет? Тогда как я узнаю, какие потребители простаивают и отменяются? В этих сообщениях журнала нет информации о потребителе. - person nsdiv; 24.02.2016
comment
Вы не должны беспокоиться о consumer с точки зрения container. У вас есть, да, контейнер. Но я согласен с вами, что эти журналы должны быть улучшены, по крайней мере, с beanName контейнера. В Spring AMQP 1.6 мы выдаем ListenerContainerIdleEvent: docs.spring.io/spring-amqp/docs/1.6.0.BUILD-SNAPSHOT/reference/ - person Artem Bilan; 24.02.2016
comment
Ну, в любом случае, я хотел бы попросить у вас тикет JIRA о beanName в тех журналах от container. Мне кажется, это должно быть полезно для анализа журналов для аналогичной проблемы. - person Artem Bilan; 24.02.2016