RabbitMQ Spring模板抛出发送15条消息后尝试使用已关闭的通道

时间:2014-03-23 21:58:27

标签: java spring rabbitmq amqp spring-amqp

我第一次尝试使用RabbitMQ并决定使用Spring AMQP包装器。我计划首先测试写入性能并将发送者设置为队列:

Spring设置:

<rabbit:connection-factory id="connectionFactory" host="localhost" 
                           username="guest" password="guest" />

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

<rabbit:template id="myTemplate" connection-factory="connectionFactory"
                 exchange="myQueue"/>

Sender Main:

    ApplicationContext context = new ClassPathXmlApplicationContext(
                                             "th/rabbit-sender-context.xml");
    AmqpTemplate aTemplate = (AmqpTemplate) context.getBean("myTemplate");

    int total = 1000;
    for (int i = 0; i < total; i++) {
        System.out.println(i);
        aTemplate.convertAndSend("my.routingkey.1", "#"+i+" on "+new Date());
    }

但是,在发送15条消息后,客户端失败并出现以下异常:

Caused by: com.rabbitmq.client.AlreadyClosedException: clean connection shutdown; reason: Attempt to use closed channel
at com.rabbitmq.client.impl.AMQChannel.ensureIsOpen(AMQChannel.java:190)
at com.rabbitmq.client.impl.AMQChannel.transmit(AMQChannel.java:291)
at com.rabbitmq.client.impl.ChannelN.basicPublish(ChannelN.java:636)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.amqp.rabbit.connection.CachingConnectionFactory$CachedChannelInvocationHandler.invoke(CachingConnectionFactory.java:365)
at com.sun.proxy.$Proxy4.basicPublish(Unknown Source)
at org.springframework.amqp.rabbit.core.RabbitTemplate.doSend(RabbitTemplate.java:675)
at org.springframework.amqp.rabbit.core.RabbitTemplate$1.doInRabbit(RabbitTemplate.java:351)
at org.springframework.amqp.rabbit.core.RabbitTemplate.execute(RabbitTemplate.java:627)
... 9 more

怎么回事?

2 个答案:

答案 0 :(得分:1)

看看你的兔子配置。

你的amqp模板'myTemplate'是用交换'myQueue'设置的..是吗?有没有名为'myQueue'的交易所,或者这是你队列的名字?如果没有,请创建一个交换,然后将该路由密钥设置为所需的队列。

如果设置了无效的Exchange,则不会为您的模板打开/获取任何通道,从而导致AlreadyClosedException。

答案 1 :(得分:1)

正如Diogo所提到的,通道上的任何无效操作(例如,尝试从不存在的队列中消耗)都会导致通道关闭。一旦通道关闭,它就不能再使用了 - 这就是你看到AlreadyClosedException的原因。

如果出现意外的频道或连接关闭问题,您可以使用Lyra之类的客户端自动为您恢复。