RabbitMQ
RabbitMQ是实现了高级队列消息协议(AMQP: Advanced Message Queuing Protocol)的开源消息代理软件,它也被称作为面向消息的中间件。RabbitMQ服务器使用了Erlang语言编写而成,它具有高性能,可伸缩的特性。
1.安装
各个平台的安装请参考官网链接:RabbitMQ安装
2.基本概念
2.1 RabbitMQ角色定义
- Producer:消息生产者。生产并发送消息。
- Consumer:消息消费者。接受并处理消息。
- Borker:消息队列服务器的实体。他负责接受生产者产生的消息,并将消息发送至接收者或者其它的Broker。
- Exchange:消息交换机。消息被创建后第一个到达的地方,通过它指定的路由规则,将消息分发到不同的消息队列中去。
- Routing Key:路由关键字。Exchange根据这个关键字进行消息的投递。
- Queue:消息队列。消息被发送及路由之后到达的地方。到达Queue的消息即进入了等待消费的状态。每一个消息都可以被发送到一个或多个交换机。
- Binding:绑定。连接Exchange和Queue,将它们按照路由规则绑定起来。
- Virtual Host:虚拟主机。是对Broker的虚拟划分,将消费者,生产者及它们依赖的AMQP相关的结构进行隔离。
- Connection:连接。生产者,消费者及Broker之间进行通信的物理网络。
- Channel:消息通道。用于连接生产者和消费者。在每一个连接里,可以建立多个Channel,每一个Channel代表一次回话任务,使用Channel可以隔离同一个连接中的不同的交互内容。
2.2 Exchange类型
- Direct交换机:完全根据消息的Routing Key进行消息投递。
- Topic交换机:对Routing Key进行模式匹配后进行消息投递。使用
#
匹配一个或者多个词,使用*
匹配正好一个词。 - Fanout交换机:不需要任何Key,采用广播模式的方式将一个消息投递到与该交换机绑定的所有队列。
2.3 消息持久化
- Exchange持久化:声明时指定
durable
等于1(1是持久化)。 - Queue持久化:声明时指定
durable
等于1(1是持久化)。 - 消息持久化:声明时指定
delivery_mode
等于2(1是非持久化)。
3.消息投递大致流程
- 客户端连接消息队列服务器并打开一个Channel。
- 客户端声明一个Exchange并设置相关属性。
- 客户端声明一个Queue并设置相关属性。
- 客户端使用Routing Key在Exchange和Queue之间建立绑定关系。
- 客户端投递消息到Exchange。
- Exchange根据根据消息的Key和已经设置的Binding进行消息路由,将消息投递到一个或多个Queue里。
4.Spring Boot应用整合RabbitMQ
4.1 准备
安装并开启RabbitMQ服务
4.2 构建SpringBoot应用
-
新建一个Spring Boot工程
-
添加依赖:spring-boot-starter-amqp
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency>
-
配置RabbitMQ
spring: rabbitmq: host: 127.0.0.1 port: 5672 userName: admin password: admin virtual-host: /
-
RabbitMQ配置类
@Configuration public class RabbitConfig { /** * 声明交换机 * String: 交换机名称 * Boolean: 是否持久化 * Boolean: 是否自动删除 */ /** Direct Exchange **/ @Bean public DirectExchange directExchange() { return new DirectExchange("DIRECT_EXCHANGE", true, false); } /** Topic Exchange **/ @Bean public TopicExchange topicExchange() { return new TopicExchange("TOPIC_EXCHANGE", true, false); } /** Fanout Exchange **/ @Bean public FanoutExchange fanoutExchange() { return new FanoutExchange("FANOUT_EXCHANGE", true, false); } /** * 声明消息队列 * String: 消息队列名称 * Boolean: 是否持久化 */ @Bean public Queue helloQueue() { return new Queue("HELLO_QUEUE", true); } @Bean public Binding helloBinding() { return BindingBuilder.bind(helloQueue()).to(directExchange()).with("mq.hello"); } }
-
RabbitMQ生产者
@Component public class producer { @Autowired private AmqpTemplate rabbitTemplate; public void send() { rabbitTemplate.convertAndSend("HELLO_QUEUE", "hello mq!"); } }
-
RabbitMQ消费者
@Component @RabbitListener(queues = "HELLO_QUEUE") public class consumer { @RabbitHandler public void process(String message) { System.out.println(message); } }