2011-07-06 16 views
5

如果我已经创建了一个独占且耐用的队列(不是自动删除)。现在,如果消费者订阅了该队列,然后它就停止了。然后,该队列被删除。使用独家+耐用队列,用于RabbitMQ

我检查了场景,当队列只是耐用(即既不排除也不自动删除)。现在,如果消费者订阅了该队列,然后它就停止了。然后,该队列被删除。

请说明第一种情况,第二种情况是给出预期结果。在这两种情况下,只有一个消费者订阅了一个队列,并且只有一个队列绑定到一个direct_exchange。

回答

15

如果您有一个排他的队列,那么当宣布队列的通道关闭时,队列将被删除。

如果您有一个自动删除的队列,那么当该队列中没有订阅时,它将被删除。

这两个规则甚至适用于持久队列。

+1

他们为什么要这样做?我非常喜欢排他性功能(锁定),但是当处理消息的服务关闭时,不能承担排队中的消息。我只能有一个服务运行处理消息,当它停机时,故障恢复服务将检测到它现在可以拥有排队权并获得所有权。但是如果消息消失了!这对我来说毫无用处。 – code5

+2

回答这个古代的问题,因为它花了我一段时间才找出答案:你真正想要的是独占消费,而不是排他性的排队。 – Hobblin

6

有一件事要纠正,在连接关闭关闭而不是通道关闭后,专有队列将被删除。你可以运行这个测试:

package rabbitmq.java.sample.exclusivequeue; 

import java.io.IOException; 

import com.rabbitmq.client.*; 
import com.rabbitmq.client.AMQP.Queue.DeclareOk; 

public class Producer { 

    private final static String QUEUE_NAME = "UserLogin2"; 
    private final static String EXCHANGE_NAME = "user.login"; 

    /** 
    * @param args 
    */ 
    public static void main(String[] args) { 
     ConnectionFactory factory=new ConnectionFactory(); 
     factory.setHost("CNCDS108"); 
     try { 
      Connection conn = factory.newConnection();   
      Channel channel =conn.createChannel(); 
      DeclareOk declareOk = channel.queueDeclare(QUEUE_NAME, false, true, false, null); 

      channel.basicPublish("", QUEUE_NAME, null, "Hello".getBytes()); 

      //close the channel, check if the queue is deleted 
      System.out.println("Try to close channel"); 
      channel.close(); 
      System.out.println("Channel closed"); 

      System.out.println("Create a new channel"); 
      Channel channel2 =conn.createChannel(); 
      DeclareOk declareOk2 = channel2.queueDeclarePassive(QUEUE_NAME); 

      **//we can access the exclusive queue from another channel 
      System.out.println(declareOk2.getQueue()); //will output "UserLogin2" 
      channel2.basicPublish("", QUEUE_NAME, null, "Hello2".getBytes()); 
      System.out.println("Message published through the new channel");** 

//   System.out.println("Try to close Connection"); 
//   conn.close(); 
//   System.out.println("Connection closed"); 


     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 

} 
相关问题