我正在使用 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 比较 但没有帮助。
第一次更新:
我可以缩小问题范围。 在测试中,我调用 sendAndReceive() 到 HystrixCommand 内的队列(来自 Netflix)。此 HystrixCommand 使用比 RabbitTemplate 中默认回复超时(5 秒)更小的超时(2 秒)。
服务正在监听该声明的队列并返回答案。
我有一个特定的测试来对不存在的队列执行 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
感谢您的帮助/解释。
我不知道有任何变化(但没有看过),但无论如何,1.5.0.M1 是预发行版
milestone
,1.5.0.RELEASE 是发行版。当实际版本可用时,切勿使用里程碑。当前版本是 1.5.3.RELEASE。