优质博文:IT-BLOG-CN
RabbitMQ
是实现高级消息队列协议(AMQP:Advanced Message Queue Protocol
)的开源代理软件,也称为面向消息的中间件。支持多种操作系统、多种编程语言。RabbitMQ
服务器使用Erlang
语言编写,其集群和故障转移是构建在开放电信平台框架上的。
AMQP
是一个面向消息中间件的开放式应用层协议。定义消息方向、消息队列、消息路由、可靠性、安全性等特性。要求消息的提供者和客户端接收者的行为要实现对不同供应商可以用相同的方式(FTP/HTTP/SMTP
等)进行互相操作。以往的JMS
,主要是建立在API
级别,建立标准化的程序间的互操作性。而AMQP
是一个线路级协议。描述的是通过网络发送的数据传输格式,任何符合该数据格式的消息发送和接收工具都能互相兼容和进行操作,这样就可以实现跨技术平台的架构方案。
一、基本概念
【1】Broker
: 消息队列服务器的实体,负责接收生产者的消息,然后将消息发送到消息接受者或者其他Broker
。
【2】Exchange
: 消息交换机,消息第一个到达的地方,消息通过它指定的路由规则,分发到不同的消息队列中去。
【3】Queue
: 消息队列,消息通过发送和路由之后最终到达的地方,到达Queue
的消息即进入逻辑上等待消费的状态。每个消息都会被发送到一个或多个队列。
【4】Binding
: 绑定,它的作用是把Exchange
和Queue
按照路由规则绑定起来(虚拟连接)。
【5】Routing Key
: 路由关键字,Exchange
根据这个关键字进行消息投递。
【6】Virtual host
: 虚拟主机,它是对Broker
的虚拟划分,将消费者、生产者和他们依赖的AMQP
相关结构进行隔离,一般都是为了安全考虑。比如,我们可以在一个Broker
中设置多个虚拟主机,对不同用户进行权限管理。
【7】Connection
: 连接,代表生产者、消费者、Broker
之间进行通信的物理网络。
【8】Channel
: 消息通道,用户连接生产者与消费者的逻辑结构。在客户端的每个连接里,可建立多个Channel
,每个Channel
,每个Channel
代表一个会话任务,通过Channel
可以隔离同一连接中的不同交互内容。
【9】Producer
: 消息生产者,制造消息并发送消息的程序。
【10】Consumer
: 消息消费者,接收消息并处理消息的程序。
二、消息传递到队列的过程
【1】客户端连接到消息队列服务器,打开一个Channel
。
【2】客户端声明一个Exchange
,并设置相关属性。
【3】客户端声明一个Queue
,并设置相关属性。
【4】客户端使用Routing Key
,在Exchange
和Queue
之间建立好绑定关系。
【5】客户端投递消息到Exchange
。
【6】Exchange
接收到消息后,根据消息的Key
和已经设置的Binding
,进行消息路由,将消息传递到一个或多个Queue
里。
三、Exchange 三种类型
【1】Direct
交换机: 完全根据Key
进行投递。比如,绑定时设置了 Routing Key
为abc
,那么客户端提交的消息,只有设置了Key
为abc
的才会被投递到队列。
【2】Topic
交换机: 对Key
进行模式匹配后进行投递,可以使用符号#
匹配一个或多个词,符号*
匹配正好一个词。比如,abc.#
匹配abc.efg.dwg
,abc.*
只匹配类似abc.efg
。
【3】Fanout
交换机: 不需要任何Key
,它采用广播模式,一个消息进来时,投递到与该交换机绑定的所有队列。
四、RabbitMQ 持久化策略
为了数据安全考虑,大多数情况下都会选择持久化,也就是将数据写到磁盘上。消息持久化包括以下3
个部分:
【1】Exchange
持久化,在声明时指定durable => 1
;
【2】Queue
持久化,在声明时指定durable => 1
;
【3】消息持久化,在投递时指定delivery_mode => 2
(1
是非持久化)
如果Exchange
和Queue
都是持久化的,那么他们之间的Binding
也是持久化的,如果Exchange
和Queue
两者之间有一个是持久化的,一个是非持久化的。就不允许建立绑定。
五、RabbitMQ 管理
我们可以直接通过访问配置文件进行管理,也可以通过访问Web
进行管理,我们主要介绍通过Web
进行管理。
配置完环境之后,在cmd
窗口执行rabbitmq-plugins enable rabbitmq_management
命令,开启Web
管理插件。
六、快速入门
通过Spring Boot
应用整合RabbitMQ
,实现一个简单的发送、接收消息的例子。在Spring Boot
中添加AMQP
的Starter
即可。
【1】创建一个SpringBoot
工程,命名为rabbitmq-hello
;
【2】在pom.xml
中引入如下依赖内容:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
【3】在application.yml
中配置关于RabbitMQ
的连接和用户信息:
spring:
application:
name: rabbitmq-hello
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
【4】创建消息生产者Sender
,通过注入AmqpTemplate
接口的实例来实现消息的发送,AmqpTemplate
接口定义了一套针对AMQP
协议的基本操作。在 SpringBoot
中会根据配置注入其具体实现。在该生产者汇总,我们会产生一个字符串,并向队列名为hello
中发送消息。
@Component
public class Sender {
@Autowired
private AmqpTemplate rabbitTemp;
public void send(){
String context = "hello "+new Date();
System.out.println("Sender : " + context);
this.rabbitTemp.convertAndSend("hello",context);
}
}
【5】创建消费者Receiver
,通过@RabbitListener
注解定义该类对hello
队列的监听,并用@RabbitHandler
注解来指定对消息的处理方法。
@Component
@RabbitListener(queues = "hello")
public class Receiver {
@RabbitHandler
public void process(String hello){
System.out.println("Receviver:"+hello);
}
}
【6】创建RabbitMQ
的配置类RabbitConfig
,用来配置队列,交换器、路由等高级特性。
@Configuration
public class helloQueue {
```