目录
安装与配置
- Downloading and Installing RabbitMQ :https://www.rabbitmq.com/download.html
- RabbitMQ中文文档:RabbitMQ中文文档 · RabbitMQ in Chinese
- 教程:https://www.rabbitmq.com/getstarted.html
- 常用指令
| 启动 | rabbitmqctl -server -detached |
| 查看是否启动成功 | rabbitmqctl status |
| 查看集群信息 | rabbitmqctl cluster_status |
| 创建用户 | rabbitmqctl add_user username psd |
| 设置用户所有权限 | rabbitmqctl set_permissions -p/username ". *" ". *" ". *" |
| 设置用户权限 | rabbitmqctl [--node ] [--longnames] [--quiet] set_permissions [--vhost ] |
| 命令帮助 | rabbitmqctl help |
AMQP协议介绍
消息队列的运转过程如下图所示,首先生产者将业务方数据进行可能的包装,之后封装 成消息,发送(AMQP协议里这个动作对应的命令为Basic.Publish)到Broker中。消费者订阅并接收消息(AMQP协议里这个动作对应的命令为 Basic.Consume或者Basic.Get),经过可能的解包处理得到原始的数据,之后再进行业务处理逻辑。这个业务处理逻辑并不一定需要和接收消息的逻辑使用同一个线程。 消费者进程可以使用一个线程去接收消息, 存入到 内存中,比如使用Java中的BlockingQueue。业务处理逻辑使用另一个线程从内存中读取数据,这样可以将应用进一步解耦,提高整个应用的处理效率。

AMQP协议本身包括三层:
- Module Layer:位于协议最高层,主要定义了一些共客户端调用的命令,客户端可以利用这些命令实现自己的业务逻辑。如:Queue.Declare命令用于声明队列。
- Session Layer:位于中间层,主要负责将客户端命令发送给服务器,再将服务器端的应答返回给客户端,主要为客户端与服务器之间的通信提供可靠性同步机制和错误处理。
- Transport Layer:位于最底层,主要传输二进制数据流,提供帧的处理、信道复用、错误检测和数据表示等。
| AMQP生产者流转过程 | AMQP 消费者流转过程(推模式) |
![]() |
![]() |
更多信息可以在AMQP官网下下载,RabbitMQ使用的是0-9-1版。
客户端开发(连接、交换机、队列、生产/消费消息)
基础概念
- 生产者/消费者:消息的发送方和消费方。消息一般包括消息体和标签两部分。消息体一般是带有业务逻辑的数据,标签一般用来描述消息。消费时,只能消费消息的消息体。消息在路由过程中,消息标签会丢弃,只有消息体才能存入队列中。
- 队列:用于存储消息,当多个消费者订阅统一队列时,默认采用平均分摊(轮询)规则处理消息。
- 交换机:RabbitMQ中,生产者将消息发送到交换机,然后再通过路由键(Routing Key)将消息路由到与绑定建(Binding Key)匹配的队列中。点对点模式时,可以直接发送给队列。
- 路由键:生产者将消息发送给交换机时,一般会指定一个RoutingKey,用来指定这个消息的路由规则。
- 绑定键:通过绑定键把交换机与队列关联起来。结合生产者指定的RoutingKey,才可以正确的将消息路由到队列。
生产者将消息发送给交换器时, 需要一个 RoutingKey,当BindingKey和RoutingKey相 匹配时,消息会被路由到对应的队列中。 在绑定多个队列到同一个交换器的时候,这些绑定允许使用相同的BindingKey。BindingKey并不是在所有的情况下都生效,它依赖于交换器 类型,比如fanout类型的交换器就会无视 BindingKey,而是将消息路由到所有绑定到该交换器的队列中。
交换机类型
- fanout:将消息路由到所有绑定到该交换器的队列中
- direct:把消息路由到BindingKey和RoutingKey完全匹配的队列中
- topic规则:
- RoutingKey为一个点号“.”分隔的字符串(被点号“.”分隔开的每一段独立的字符串称为一个单词), 如“com. rabbitmq. client”、“java. util. concurrent”、“com. hidden. client”;
- BindingKey和RoutingKey一样也是点号“.”分隔的字符串;
- BindingKey中可以存在两种特殊字符串“*”和“#”,用于做模糊匹配,其中“*”用于匹配一个单词,“#”用于匹配多规格单词(可以是零个)。
- 举例:

(1) 路由键为“com. rabbitmq. client”的消息会同时路由到Queue1和Queue2;
(2) 路由键为“com. hidden. client”的消息只会路由到Queue2 中;
(3) 路由键为“com. hidden. demo”的消息只会路由到Queue2 中;
(4) 路由键为“java. rabbitmq. demo”的消息只会路由到Queue1中;
(5) 路由键为“java. util. concurrent”的消息将会被丢弃或者返回给生产者(需要设置mandatory参数),因为它没有匹配任何路由键。
RabbitMQ运转流程
- 生产者生产消息过程:
(1) 生产者连接到RabbitMQ Broker,建立一个连接(Connection),开启一个信道(Channel)。
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost(HOST);
connectionFactory.setPort(PORT);
/**
* 如果配置有用户名密码以及vhost,则配置即可。
*/
connectionFactory.setUsername(USERNAME);
connectionFactory.setPassword(PASSWORD);
connectionFactory.setVirtualHost(VIRTUALHOST);
//使用uri方式
//connectionFactory.setUri(“qmqp://userName:password@ipAddress:protNumber/virtualHost”);
Connection connection = ConnectionUtils.getConnection();
Channel channel = connection.createChannel();
Connection可以用来创建多个Channel实例,但是Channel实例不能在线程间共享,多线程共享Channel实例是线程不安全的,应用程序应该为每个线程开辟一个channel。
慎用Connection或者Channel的isOpen方法检测是否处于开启状态。
(2) 生产者声明一个交换器,并设置相关属性,比如交换机类型是否持久化等。
channel.exchangeDeclare("exchange.confirm", "direct", true, false, null);
- 函数Exchange.DeclareOk exchangeDeclare参数介绍,有多个重载方法:
(1) String exchange:交换机名称
(2) String type:交换机类型(fanout/direct/topic)
(3) boolean durable:是否持久化;持久化后服务器重启不丢失相关信息
(4) boolean autoDelete:是否自动删除,自动删除的前提是至少有一个队列或者交换器与这个交换器绑定,之后所有与这个交换器绑定的队列或者交换器都与此解绑。
(5) boolean Internal:设置是否是内置的。如果设置为true,则表示是内置的交换器,客户端程序无法直接发送消息到这个交换器中,只能通过交换器路由到交换器这种方式。
(6) Map<String,Object> arguments:其他结构化参数
- void exchangeDeclareNoWait方法,多了一个nowait参数,不建议使用。
- Exchange.DeclareOk exchangeDeclarePassive(String name)方法,主要用来检测交换机是否存在,存在正常返回,不存在抛出异常。
- 其他方法可以在Channel接口中查看。
(3) 生产者声明一个队列并设置相关属性,比如是否排他、是否持久化、是否自动删除等。

本文详细介绍了RabbitMQ的安装配置、AMQP协议的工作原理、消息的生产消费流程,包括交换机类型、队列操作、死信、延迟和优先级队列。此外,还深入探讨了消费端的消息确认与拒绝机制,以及消息的分发、顺序性和传输保障。最后,讲解了队列结构、存储机制和流量控制,帮助读者全面理解RabbitMQ的运作机制。



1922

被折叠的 条评论
为什么被折叠?



