Выключение канала: ошибка канала: код-ответа = 406, текст-ответа = PRECONDITION_FAILED - получатель ответа уже установлен

Я запускаю несколько тестов с spring-amqp, spring-rabbit. Мой родительский элемент Maven - это spring-boot-starter-parent: 1.2.3.RELEASE, который извлекает:

spring-rabbit:1.4.3.RELEASE
    spring-amqp:1.4.3.RELEASE
    amqp-client:3.4.2

В какой-то момент один из тестов выдает эту ошибку, и я не вижу причины:

Executing callback on RabbitMQ Channel: Cached Rabbit Channel: AMQChannel(amqp://[email protected]:5672/,2119)
Channel shutdown: channel error; protocol method: #method<channel.close>(reply-code=406, reply-text=PRECONDITION_FAILED - reply consumer already set, class-id=60, method-id=20)
Detected closed channel on exception.  Re-initializing: null

Если я перейду на spring-boot-starter-parent: 1.3.1.RELEASE, все тесты пройдены.

Копаясь в разных версиях, кажется, что я все еще могу воспроизвести неудавшийся тест с

spring-rabbit:1.5.0.M1
    spring-amqp:1.5.0.M1
    amqp-client:3.5.5

но все тесты проходят с

spring-rabbit:1.5.0.RELEASE
    spring-amqp:1.5.0.RELEASE
    amqp-client:3.5.5

Есть ли какое-либо соответствующее изменение между 1.5.0.M1 и 1.5.0.RELEASE, которое могло бы ответить на этот вопрос? Я попытался просмотреть GitHub compare но не помогло.

1-е обновление:

Я мог бы сузить вопрос. В тестах я вызываю sendAndReceive () в очередь внутри HystrixCommand (из Netflix). Эта HystrixCommand использует меньшее время ожидания (2 секунды), чем время ожидания ответа по умолчанию (5 секунд) в RabbitTemplate.

Служба прослушивает объявленную очередь и возвращает ответ.

У меня есть определенный тест, чтобы выполнить sendAndReceive () для несуществующей очереди. Когда выполняется этот специальный тест, тайм-аут HystrixCommand истекает.

Следующий тест, выполняющий sendAndReceive () в объявленной очереди, дает ошибку канала.

@SpringBootApplication
public class SpringAmqpTestApplication implements CommandLineRunner {

    public static final String QUEUE_NAME = "Spring-AMQP-Test";
    private static final String NONEXISTENT_QUEUE_NAME = UUID.randomUUID().toString() + "@" + System.currentTimeMillis();

    public static void main( String[] args ) {
        SpringApplication.run( SpringAmqpTestApplication.class, args );
    }

    @Autowired
    AmqpTemplate amqpTemplate;

    @Override
    public void run( String... args ) throws Exception {
        sendAndReceive( QUEUE_NAME );

        sendAndReceive( NONEXISTENT_QUEUE_NAME );

        sendAndReceive( QUEUE_NAME );
    }

    private void sendAndReceive( String routingKey ) {
        CustomHystrixCommand customHystrixCommand = new CustomHystrixCommand( amqpTemplate, routingKey );
        String answer = customHystrixCommand.execute();
        System.err.println( "< sendAndReceive(): " + answer );
    }
}

Моя HystrixCommand довольно проста:

public class CustomHystrixCommand extends HystrixCommand<String> {

    private String routingKey;

    AmqpTemplate amqpTemplate;

    public CustomHystrixCommand( AmqpTemplate amqpTemplate, String routingKey ) {
        super( HystrixCommandGroupKey.Factory.asKey( "" ), 2000 );
        this.amqpTemplate = amqpTemplate;
        this.routingKey = routingKey;
    }

    @Override
    protected String run() throws Exception {
        String request = UUID.randomUUID().toString();
        MessageProperties messageProperties = new MessageProperties();
        Message message = new Message( request.getBytes(), messageProperties );
        Message answer = amqpTemplate.sendAndReceive( "", routingKey, message );
        return "OK answer";
    }

    @Override
    protected String getFallback() {
        return "getFallback()";
    }

}

С spring-boot-starter-parent: 1.2.3.RELEASE мои журналы:

< sendAndReceive(): OK answer
< sendAndReceive(): getFallback()
2016-01-27 11:47:42.266 ERROR 15007 --- [pool-1-thread-1] o.s.a.r.c.CachingConnectionFactory       : Channel shutdown: channel error; protocol method: #method<channel.close>(reply-code=406, reply-text=PRECONDITION_FAILED - reply consumer already set, class-id=60, method-id=20)
< sendAndReceive(): getFallback()

в то время как с spring-boot-starter-parent: 1.3.1.RELEASE:

< sendAndReceive(): OK answer
< sendAndReceive(): getFallback()
< sendAndReceive(): OK answer

Спасибо за любую помощь / объяснение.


person Atos    schedule 26.01.2016    source источник
comment
Поделитесь этим тестом, пожалуйста. Если вы скажете, что это не исправлено в spring-amqp:1.4.3.RELEASE, поэтому мы можем играть локально и воспроизводить. С другой стороны не уверен, имеет ли смысл бороться, когда подтверждаешь, что все работает с 1.5 или новее.   -  person Artem Bilan    schedule 26.01.2016


Ответы (1)


Мне не известны какие-либо изменения (но я не смотрел), но в любом случае 1.5.0.M1 - это предварительный выпуск milestone, а 1.5.0.RELEASE - это выпуск. Вехи никогда не следует использовать, когда доступен фактический выпуск. Текущая версия - 1.5.3.RELEASE.

person Gary Russell    schedule 26.01.2016