• 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();
            }
        }
    
    }
  • 相关阅读:
    ArrayBlockingQueue和LinkedBlockingQueue
    hibernate中保存一个对象后再设置此对象的属性为什么不需要调用update方法了
    Hello World!
    org.springframework.transaction.CannotCreateTransactionException: Could not open JDBC Connection for transaction;
    jquery的attr在浏览器发生错误,checkbox的属性总是为undefined
    如何解决设置maven时Could not read settings.xml
    iOS与HTML交互问题
    一个苹果证书怎么多次使用——导出p12文件
    Mac Chrome-点击书签页在新的标签打开之方法
    iOS 开发者中的个人账号与组织账号之间区别
  • 原文地址:https://www.cnblogs.com/rader/p/2567779.html
Copyright © 2020-2023  润新知