1、消息队列
在介绍RabbitMQ之前先介绍一下消息队列,即MQ,(Message Queue)
![](https://img.haomeiwen.com/i13372635/b08568673e4f74b9.png)
消息队列是典型的:生产者、消费者模型。生产者不断向消息队列中生产消息,消费者不断的从队列中获取消息。因为消息的生产和消费都是异步的,而且只关心消息的发送和接收,没有业务逻辑的侵入,这样就实现了生产者和消费者的解耦。
2.AMQP和JMS
MQ是消息通信的模型,并不是具体实现。现在实现MQ的有两种主流方式:AMQP、JMS。
![](https://img.haomeiwen.com/i13372635/b02b4a3ac68b6acc.png)
两者间的区别和联系:
- JMS是定义了统一的接口,来对消息操作进行统一;AMQP是通过规定协议来统一数据交互的格式
- JMS限定了必须使用Java语言;AMQP只是协议,不规定实现方式,因此是跨语言的。
- JMS规定了两种消息模型;而AMQP的消息模型更加丰富
3.常见MQ产品
- ActiveMQ:基于JMS
- RabbitMQ:基于AMQP协议,erlang语言开发,稳定性好
- RocketMQ:基于JMS,阿里巴巴产品,目前交由Apache基金会
- Kafka:分布式消息系统,高吞吐量
4.RabbitMQ
RabbitMQ是基于AMQP的一款消息管理系统
官网: http://www.rabbitmq.com/
官方教程:http://www.rabbitmq.com/getstarted.html
![](https://img.haomeiwen.com/i13372635/c3b34beea8bb862f.png)
4.1安装
这里我采用docker的方式安装rabbitMQ
- 拉取镜像
docker pull rabbitmq:management
- 安装容器
docker run -d --restart=always --name rabbitmq -p 5672:5672 -p 15672:15672 e58249ecc163
- 开放rabbitMQ端口
firewall-cmd --zone=public --add-port=5672/tcp --permanent
firewall-cmd --zone=public --add-port=15672/tcp --permanent
- 重启防火墙
systemctl restart firewalld.service
- 通过宿主机ip访问
http://192.168.220.128:15672
默认用户名密码:guest:guest
![](https://img.haomeiwen.com/i13372635/dfc090109828bb55.png)
也可以自定义用户
![](https://img.haomeiwen.com/i13372635/9c30feea7e0a2899.png)
5.五种消息模型
RabbitMQ提供了6种消息模型,但是第6种其实是RPC,并不是MQ,因此不予学习。那么也就剩下5种。
但是其实3、4、5这三种都属于订阅模型,只不过进行路由的方式不同。
![](https://img.haomeiwen.com/i13372635/fc30c7e41b59835c.png)
官方描述:
RabbitMQ是一个消息代理:它接受和转发消息。 你可以把它想象成一个邮局:当你把邮件放在邮箱里时,你可以确定邮差先生最终会把邮件发送给你的收件人。 在这个比喻中,RabbitMQ是邮政信箱,邮局和邮递员。
RabbitMQ与邮局的主要区别是它不处理纸张,而是接受,存储和转发数据消息的二进制数据块。
6.项目中的使用
项目中我们一般都采用Spring-amqp来完成消息队列的使用
Spring-amqp是对AMQP协议的抽象实现,而spring-rabbit 是对协议的具体实现,也是目前的唯一实现。底层使用的就是RabbitMQ。
6.1步骤
- 引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
- 在
application.yml
中添加RabbitMQ地址:
spring:
rabbitmq:
host: 192.168.56.101
username: leyou
password: leyou
virtual-host: /leyou
- 配置监听者
在SpringAmqp中,对消息的消费者进行了封装和抽象,一个普通的JavaBean中的普通方法,只要通过简单的注解,就可以成为一个消费者。
@Component
public class Listener {
@RabbitListener(bindings = @QueueBinding(
value = @Queue(value = "spring.test.queue", durable = "true"),
exchange = @Exchange(
value = "spring.test.exchange",
ignoreDeclarationExceptions = "true",
type = ExchangeTypes.TOPIC
),
key = {"#.#"}))
public void listen(String msg){
System.out.println("接收到消息:" + msg);
}
}
- @Componet`:类上的注解,注册到Spring容器
- @RabbitListener:方法上的注解,声明这个方法是一个消费者方法,需要指定下面的属性:
- bindings:指定绑定关系,可以有多个。值是@QueueBinding的数组。@QueueBinding包含下面属性:
- value:这个消费者关联的队列。值是@Queue,代表一个队列
- exchange:队列所绑定的交换机,值是@Exchange类型
- key:队列和交换机绑定的RoutingKey
- bindings:指定绑定关系,可以有多个。值是@QueueBinding的数组。@QueueBinding包含下面属性:
类似listen这样的方法在一个类中可以写多个,就代表多个消费者。
6.2 AmqpTemplate
Spring最擅长的事情就是封装,把他人的框架进行封装和整合。
Spring为AMQP提供了统一的消息处理模板:AmqpTemplate,非常方便的发送消息,其发送方法:
![](https://img.haomeiwen.com/i13372635/1c0f7c77106a1713.png)
红框圈起来的是比较常用的3个方法,分别是:
- 指定交换机、RoutingKey和消息体
- 指定消息
- 指定RoutingKey和消息,会向默认的交换机发送消息
网友评论