RabbitMQ学习之入门篇-笔记2

44 阅读5分钟

一、使用交换器和队列

交换器和队列是AMQP的high-level层面的构建模块,应用程序需确保在使用它们的时候就已经存在了,在使用之前需要先声明它们。

#声明一个交换器和队列
channel.exchangeDeclare (exchangeName , "direct" , true) ;
channel.queueDeclare(queueName , true , false , false , null);
channel.queueBind(queueName , exchangeName , routingKey) ;
#这里的队列被声明为持久化的,非排他的,非自动删除的,而且也被分配另一个确定的己知的名称。

1.exchangeDeclare 方法详解

(1)exchange:交换器的名称。

(2)type:交换器的类型,常见的如fanout,direct,topic

(3)durable: 设置是否持久,设置为true表示持久化,反之是非持久。持久化可以将交换器存盘,在服务器重启的时候不会丢失信息。

(4)autoDelete:设置是否自动删除。设置为true表示自动删除。自动删除的前提是:至少有一个队列或者交换器与这个交换器绑定,之后所有与这个交换器绑定的队列或者交换器都与解绑。

(5)internal:设置是否是内置的。如果设置为true ,则表示是内置的交换器,客户端程序无法直接发送消息到这个交换器中,只能通过交换器路由到交换器这种方式。

(6)argument:其他一些结构化参数

———————————————————————————————————————————

2.queueDeclare 方法详解

channel.queueDeclare();
channel.queueDeclare(queueName , true , false , false , null);

不带任何参数的queueDeclare方法默认创建一个由RabbitMQ命名的(类似这种amq.gen-LhQzlgv3GhDOv8PID名称,这种队列也称之为匿名队列)、排他的、自动删除的、非持久化的队列。

参数:

queue:队列的名称。

durable: 设置是否持久化。为 true 则设置队列为持久化。持久化的队列会存盘,在服务器重启的时候可以保证不丢失信息。

exclusive:设置是否排他。为true则设置队列为排他的。如果一个队列被声明为排他队列,该队列仅对首次声明它的连接可见,并在连接断开时自动删除。这里需要注意三点:排他队列是基于Connection可见的,同一个连接的不同信道 (Channel)是可以同时访问同一连接创建的排他队列; "首次"是指如果一个连接己经声明了 排他队列,其他连接是不允许建立同名的排他队列的,这个与普通队列不同,即使该队列是持久化的,一旦连接关闭或者客户端退出,该排他队列都会被自动删除,这种队列适用于一个客户端同时发送和读取消息的应用场景。

autoDelete: 设置是否自动删除。为 true 则设置队列为自动删除。自动删除的前提是:至少有一个消费者连接到这个队列,之后所有与这个队列连接的消费者都断开时,才会自动删除。不能把这个参数错误地理解为: "当连接到此队列的所有客户端断开时,这个队列自动删除",因为生产者客户端创建这个队列,或者没有消费者客户端与这个队列连接时,都不会自动删除这个队列。

argurnents: 设置队列的其他一些参数,如 x-rnessage-ttl,x-expires-rnax-length,x-rnax-length-bytes,x-dead-letter-exchange,x-dead,letter-routing-key,x-rnax-priority等。

3.queueBind 方法详解

channel.queueBind(queueName , exchangeName , routingKey) ;

queue: 队列名称:

exchange: 交换器的名称:

routingKey: 用来绑定队列和交换器的路由键;

argument: 定义绑定的一些参数。

4.exchangeBind 方法详解 (将交换器与交换器绑定)

channel.exchangeDeclare("source","direct",false,true, null);
channel.exchangeDeclare("destination", "fanout",false,true,null);
channel.exchangeBind("destination","source","exKey");
channel.queueDeclare("queue",false,false,true,null);
channel.queueBind("queue",destnation,"") ;
channel.basicPublish("source","exKey",null,"exToExDemo".getBytes()) ;

image.png

QPS:即每秒查询率,是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准.

5.发送消息

下面这行代码发送了一条消息,这条消息的投递模式 deliveryMode设置为2,即消息会被持久化(即存入磁盘)在服务器中。同时这条消息的优先级priority设置为1。contentType为"text/plain"。可以自己设定消息的属性:
channe1.basicPub1ish(exchangeName,routingKey,
    new AMQP.BasicPropertes.Builder()
    .contentType("text/plain")
    .deliveryMode(2)
    .priority(1)
    .userld("hidden")
    .build()) ,
    messageBodyBytes);

exchange: 交换器的名称。指明消息需要发送到哪个交换器中,如果设置为空字符串则消息会被发送到RbbitMQ 默认的交换器中。

routingKey:路由键。交换器根据路由键将消息存储到相应的队列之中

props:消息的基本属性集,其包含14个属性成员,分别有contentType,contentEncoding, headers(Map<String Object>),deliveryMode,priority,correlationld,replyTo,expiration,messageld,timestamp,type,userld,appld,clusterId。

byte[] body:消息体,真正需要发送的消息

6.消费消息

消费模式分两种:推(Push)模式和拉(Pull)模式。推模式采用Basic.Consume进行消费,而拉模式则是调用Basic.Get进行消费。

(1) 推模式
接收消息一般通过实现Consumer接口或者继承DefaultConsumer类来实现。

boolean autoAck = false ;
channel.basicQos(64);
channel.basicConsume(queueName,autoAck, "myConsumerTag",
    new DefaultConsumer(channel) {
        @Override
        public void handleDelivery(String consumerTag,Envelope envelope,
            AMQP.BasicPropertes properties,byte[] body)throws IOException{
                String routingKey = envelope.getRoutingKey( );
                String contentType = properties.getContentType() ;
                long deliveryTag = envelope.getDeliveryTag() ;
                channel.basicAck(deliveryTag,false);
            }
        }) ,

queue 队列的名称。

autoAck 设置是否自动确认。建议设成false,即不自动确认。

consumerTag: 消费者标签,用来区分多个消费者。

noLocal:设置为true则表示不能将同一个Connectio口中生产者发送的消息传送给这个 Connection 中的消费者。

exclusive:设置是否排他。

arguments:设置消费者的其他参数。

callback:设置消费者的回调函数。用来处理RabbitMQ推送过来的消息,比如DefaultConsumer 使用时需要客户端重写其中的方法。