RabbitMQ:排他性隊列(Exclusive Queue)


如果你想創建一個只有自己可見的隊列,即不允許其它用戶訪問,RabbitMQ允許你將一個Queue聲明成為排他性的(Exclusive Queue)。

該隊列的特點是:

  1. 只對首次聲明它的連接(Connection)可見
  2. 會在其連接斷開的時候自動刪除。

對於第一點,首先是強調首次聲明,因為另外一個連接無法聲明一個同樣的排他性隊列;其次是只區別連接(Connection)而不是通道(Channel),從同一個連接創建的不同的通道可以同時訪問某一個排他性的隊列。這里說的連接是指一個AMQPConnection,以RabbitMQ的Java客戶端為例:

Connection conn = factory.newConnection();    

如果試圖在一個不同的連接中重新聲明或訪問(如publish,consume)該排他性隊列,會得到資源被鎖定的錯誤:

ESOURCE_LOCKED - cannot obtain exclusive access to locked queue 'UserLogin2'

對於第二點,RabbitMQ會自動刪除這個隊列,而不管這個隊列是否被聲明成持久性的(Durable =true)。 也就是說即使客戶端程序將一個排他性的隊列聲明成了Durable的,只要調用了連接的Close方法或者客戶端程序退出了,RabbitMQ都會刪除這個隊列。注意這里是連接斷開的時候,而不是通道斷開。這個其實前一點保持一致,只區別連接而非通道。

 


下面是一段示例代碼,演示了如何在同一連接的不同通道中訪問排他性隊列:

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, true, 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();
        }
    }

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM