04RabbitMQ 常用API

本文详细介绍了如何使用RabbitMQ进行连接、创建通道、设置交换机和队列。讲解了ConnectionFactory的配置,包括主机、端口、用户名和密码。此外,详细阐述了交换机的声明、检查和删除,以及队列的创建、检查和删除。提到了消息的发送方法以及消费模式,包括推模式和拉模式的使用。内容涵盖了RabbitMQ的基础操作和关键概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

连接RabbitMQ,创建Connection:

        ConnectionFactory factory = new ConnectionFactory();
        //配置访问地址与端口
        factory.setHost(IP_ADDRESS);
        factory.setPort(PORT);

        //配置账号密码
        factory.setUsername("guest");
        factory.setPassword("guest");

        //配置VirtualHost(其实是分区)
        factory.setVirtualHost("test");

        return factory.newConnection();

信道 channel:

Channel channel = connection.createChannel();

        Connection 可以用来创建多个Channel实例,但是Channel实例不能在线程之间共享,应用程序应该为每一个线程开辟一个channel 。某些情况下Chanel 的操作可以并发运行,但是在其他的情况下会导致在网络上,出现错误的通信。同时也会影响发送方确认机制的运行。所以,多线程之间共享 Channel 是非线程安全的。 

交换机 Exchange:

        exchangeDeclare有多个重载方法,这些重载的方法都是由下面这个方法中缺省的某些参数构成的。

    Exchange.DeclareOk exchangeDeclare(String exchange,
        BuiltinExchangeType type,
        boolean durable,
        boolean autoDelete,
        boolean internal,
        Map<String, Object> arguments) throws IOException;

这个方法的返回值是Exchange.DeclareOk,用来标识成功生成了一个交换机。

  • exchange:交换机的名称
  • BuiltinExchangeType:交换机进行分发的类型。
    • DIRECT
    • FANOUT
    • TOPIC
    • HEADERS
  • durable:设备是否持久化。durable设置为true表示持久化,反之非持久化。持久化可以将交换机存盘,在服务器重启的时候不会丢失信息
  • autoDelete:设备是否自动删除。autoDelete的值为true,表示自动删除。自动删除的前提是至少有一个队列或者交换器与这个交换器绑定,之后与这个交换器绑定的队列或者交换器都与此交换器解绑。注意:不能错误的把这个参数理解为:“当与此交换器连接的客户端都断开时,RabbitMQ会自动删除本交换机”
  • internal:设置是否是内置交换机。如果为true,则表示是内置的交换机。客户端程序无法发送消息到此交换机中。只能通过交换机路由到队列中。
  • arguments:其他一些结构化参数。

 检测交换机是否存在:

Exchange.DeclareOk exchangeDeclarePassive(String name) throws IOException;

         这个方法在实际开发过程中还是非常有用的,它用来检测相应的交换机是否存在。如果存在,则正常返回。如果不存在则抛出异常:404 channel Exception。同时channel也会关闭。

删除交换机

(1) Exchange.DeleteOk exchangeDelete(String exchange) throws IOException;

(2) void exchangeDeleteNoWait(String exchange, boolean ifUnused) throws IOException;

(3) Exchange.DeleteOk exchangeDelete(String exchange) throws IOException;

ifUnused :用来设置交换机没有使用的情况下删除交换机。如果ifUnused设置为true,则只有在此交换机没有被使用的情况下才会被删除;如果设置为false,则无论如何这个交换机都要被删除。

 创建队列

相对于交换机的多个方法,创建队列只有两个方法。

    (1)    Queue.DeclareOk queueDeclare();

    (2)    Queue.DeclareOk queueDeclare(String queue, boolean durable, boolean exclusive, boolean autoDelete,Map<String, Object> arguments);

 无参的方法默认创建了一个由RabbitMQ命名的、排他的、自动删除的、非持久化的队列。这种队列也被称为匿名队列。

  • queue:队列名称
    • durable:是否持久化。为true则设置队列持久化。持久化的队列会存盘,在服务器重启的时候可以保证不丢失相关信息。
    • exclusive:设置是否排他。为true则设置队列为排他的。如果一个队列被声明为排他队列,则队列则仅对声明它的连接可见。并在连接断开时自动删除。这里需要注意三点
      • 排他队列是基于连接可见的,同一个连接的不同信道是同时访问同一连接创建的排他队列;
      • “首次”是指如果一个连接已经声明了一个排他队列,其他连接是不允许建立其他的同名排他队列的,这与普通队列不同。
      • 即使该队列是持久化的,一旦连接关闭或者客户端退出,该排他队列都会被自动删除。这种队列适合一个客户端同时发送和读取消息的引用场景。
    • autoDelete:设置是否自动删除。为true则设置队列为自动删除。自动删除的前提是:至少有一个消费者连接到这个队列,之后所有与这个队列连接的消费者都断开时,才会自动删除。不能把这个参数错误的理解为当连接到此队列的所有客户端断开时,这个队列自动删除。因为生产者客户端创建这个队列,或者没有消费者客户端与这个队列连接时,都不会自动删除这个队列。
    • arguments:设置队列的其他一些参数

注意要点:生产者与消费者都能够使用queueDeclare 来声明一个队列,但是如果消费者在同一个信道上订阅了另外一个队列,就无法再声明队列了。必须先取消订阅,然后将信道设置为“传输”模式,之后才能声明队列

void queueDeclareNoWait(String queue, boolean durable, boolean exclusive, boolean autoDelete, Map<String, Object> arguments)

方法的返回值是void,表示不需要服务端的任何返回。同样也需要注意,在调用完queueDeclareNoWait方法之后,紧接着使用声明的队列时,有可能会发生异常。 

检测队列:

Queue.DeclareOk queueDeclarePassive(String queue) throws IOException;

存在返回Queue。DeclareOK。不存在抛出异常。

删除队列:

1.Queue.DeleteOk queueDelete(String queue) throws IOException;
2.Queue.DeleteOk queueDelete(String queue, boolean ifUnused, boolean ifEmpty) throws IOException;
3.void queueDeleteNoWait(String queue, boolean ifUnused, boolean ifEmpty) throws IOException;

参数基本上与交换机一致

清空队列:

Queue.PurgeOk queuePurge(String queue) throws IOException;

该方法用来清空队列的内容,而不删除队列本身。

发送消息:

void basicPublish(String exchange, String routingKey, boolean mandatory, boolean immediate, BasicProperties props, byte[] body)
            throws IOException;
  • exchange:交换机的名称,指明消息要发送到哪个交换机中。如果设置为空字符串,则消息会发送到RabbitMQ默认的交换器中。
  • routingKey:路由键,交换机根据路由键将消息存储到相应的队列中。
  • mandatory:
    • true:如果exchange根据自身类型和消息routingKey无法找到一个合适的queue存储消息,那么broker会调用basic.return方法将消息返回给生产者;
    • false:如果出现上述情况,broker会直接将消息丢弃,通俗的讲,mandatory标志告诉broker代理服务器至少将消息route到一个队列中,否则将消息return给生产者。
  • immediate:已过期
  • props:消息的基本属性集,其中包含14个成员
    • content-type:让消费者知道如何解析消息体
    • content-encoding:指消息体使用某种特殊的方式进行压缩和编码
    • message-id 和correlation-id:表示唯一消息标识和唯一响应标识,用于在工作流中实现消息跟踪
    • timestamp:消息创建时间
    • expiration:消息过期时间
    • delivery-mode:将消息写入磁盘或内存队列
    • app-id 和user-id:帮助追踪出现问题的消息发布者应用程序
    • type:标识发布者与消费者之间的契约
    • reply-on:实现消息响应的路由
    • headers:定义自定义格式的属性和实现RabbitMQ路由。

消费消息:

 RabbitMQ的消费模式有两种:

  • 推模式
  • 拉模式

推模式采用Basic.Consume进行消费。拉模式采用Basic.Get方式进行消费 

推模式:

在推模式中,可以通过持续订阅的方式来消费消息。使用到的类有:

com.rabbitmq.client.Consumer
com.rabbitmq.client.DefaultConsumer

        接收消息一般通过实现Consumer接口或继承DefaultConsumer类来实现。当调用与Consumer相关的API的方法时,不同的订阅采用不同的消费者标签(ConsumeTag)来区分彼此,在同一个Channel中的消费者也需要通过唯一的消费者标签以作区分。

(1) String basicConsume(String queue, Consumer callback) throws IOException;

(2) String basicConsume(String queue, boolean autoAck, Consumer callback) throws IOException;

(3) String basicConsume(String queue, boolean autoAck, Map<String, Object> arguments, Consumer callback) throws IOException;

(4) String basicConsume(String queue, boolean autoAck, String consumerTag, Consumer callback) throws IOException;

(5) String basicConsume(String queue, boolean autoAck, String consumerTag, boolean noLocal, boolean exclusive, Map<String, Object> arguments, Consumer callback) throws IOException;
  • queue:队列名称
  • autoAck:设置是否自动确认。建议改成false,即不自动确认。
  • consumer:消费者标签,用来区分多个消费者
  • noLocal:设置为true则表示不能将同一个connection中生产者发送的消息传送给这个Connection中的消费者
  • exclusive:设置是否排他
  • arguments:消费者的其他属性
  • callback:设置消费者的回调函数。用来处理RabbitMQ推送过来的消息,比如DefaultConsumer使用时,需要客户端重写(override)其中的方法。

对于消费者客户端来说重写handlerDelivery方法是十分方便的。更复杂的客户端会重写更多的方法。具体如下:

public void handleConsumeOk(String consumerTag)
public void handleCancelOk(String consumerTag)
public void handleCancel(String consumerTag) throws IOException
public void handleShutdownSignal(String consumerTag, ShutdownSignalException sig)
public void handleRecoverOk(String consumerTag)

        和生产者一样,消费者客户端同样需要考虑线程安全问题。消费者客户端的这些callback会被分配到与Channel不同的线程池上,这以为这消费者客户端可以安全的的调用这些阻塞方法。

        每个channel都有自己独立的线程。最常用的做法是一个channel对应一个消费者。也就意味着每个消费者之间没有任何关联。当然也可以在一个channel中维持多个消费者,但是要注意一个问题。如果channel中的一个消费者一直运行,那么其他消费者的callback会被“耽搁”     

拉模式:

拉模式的消费方式:通过channel.basicGet方法可以单条的获取消息,其返回值是GetResponse。

Channel类的basicGet方法没有其他重载方法,只有:

GetResponse basicGet(String queue, boolean autoAck) throws IOException;

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值