在大多应用中,我们系统之间需要进行异步通信,即异步消息
RabbitMQ是一个基于AMQP协议的高级消息中间件
- 功能强大,支持死信队列,优先级队列,延迟队列,重试队列等多
- 种功能无需二次开发。 性能相对还算可以,一般单机的QPS在万级左右,可以满足一般的应用场景。
- 文档说明非常丰富,社区活跃,上手容易。
- 强大的可视化管理工具。
Producer&Consumer: producer指的是消息生产者,即发送消息的,consumer消息的消费者,即接受消息的
Exchange(交换机) : 消息交换机,它指定消息按什么规则,路由到哪个队列。Exchange有4种类型:direct(默认),fanout, topic, 和headers,不同类型的Exchange转发消息的策略有所区别
direct: 单播(点对点方式),Exchange收到消息,由消息的路由关键字匹配到一个消息队列,只将消息发给这一个队列
fanout: 广播,Exchange收到消息,给它下面所有消息队列发送消息
topic: 匹配广播,Exchange收到消息,会匹配路由关键字,符合条件的消息队列将被发送
- 一般这个路由关键字用通配符#、*来指定,#代表多个单词,*代表一个单词,如user.#匹配前缀为user的所有队列,而user.*只能匹配前缀为user,后缀为一个单词的队列
Queue(消息队列) : 每个消息都会被投入到一个或多个队列
- 消息队列,提供了FIFO的处理机制,具有缓存消息的能力。
- RabbitMQ中队列消息可以设置为持久化,临时或者自动删除。
- 设置为持久化的队列,queue中的消息会在server本地硬盘存储一份,防止系统crash,数据丢失
- 设置为临时队列,queue中的数据在系统重启之后就会丢失
- 设置为自动删除的队列,当不存在用户连接到server,队列中的数据会被自动删除
Binding(绑定) : 它的作用就是把交换机(Exchange)和队列(Queue)按照路由规则绑定起来,Exchange 和Queue的绑定可以是多对多的关系
Routing Key(路由关键字) : 路交换机(Exchange)根据这个关键字进行消息投递。
Connection(连接) :AMQP连接通常是长连接,Producer和Consumer都是通过TCP连接到RabbitMQ Server的。
Channel(通道) : AMQP通过通道(channels)来处理多连接,可以把通道理解成共享一个TCP连接的多个轻量化连接。
vhost(虚拟主机) : 虚拟主机,一个消息代理(Broker)里可以开设多个虚拟主机(vhost),用作不同用户的权限分离。
- 每一个vhost本质上是一个mini-rabbitmq server,分别管理各自的 exchange,和bindings –
- vhost相当于物理的server,可以为不同app提供边界隔离
- producer和consumer连接rabbit server需要指定一个vhost
Broker(消息代理) : 实际上就是消息服务器实体。
重点理解:
假设Exchange.direct是direct类型的,producer发送信息来到broker服务器的vhost中direct类型的Exchange,该Exchange绑定了(Binding)3个消息队列,绑定规则(Routing Key)分别是user.one,user.two,user.three,这时Exchange接受到的消息中的Routing Key如果是user.one,那这个消息就会由Exchange投递到Queue1队列中,然后consumer与队列之间存在Connection,consumer可以通过连接获取队列中的消息,连接中通道(channels)来处理多连接,可以把通道理解成共享一个TCP连接的多个轻量化连接
了解重要基础概念以后,可以安装RabbitMQ进行测试加深理解
1.在linux的docker中安装RabbitMQ的镜像
docker pull rabbitmq:3-management
2.运行镜像
docker run -d -p 5672:5672 -p 15672:15672 --name myrabbitmq cc86ffa2f398(自己的镜像id)
3.登录RabbitMQ管理界面
浏览器访问虚拟机IP+15672端口 如:http://192.168.85.130:15672
默认用户和密码都是guest
1.创建Exchange交换机
2.创建Queue消息队列
3.绑定交换机和队列
点击你刚创建好的交换机
绑定队列
发送消息
由于该交换机类型是direct,所以只会给一个队列发送(消息的Routing key和绑定的Routing key相同 )
检验队列中的信息
其他类型的交换机可以自己以同样的方法操作试试,加深理解
spring.rabbitmq.host=192.168.85.130
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
/**
* 测试direct(单播)
*/
@Test
void testDirect() {
Map<String,Object> map = new HashMap<>();
map.put("name","张三");
map.put("age",11);
//对象被默认序列化发送出去
rabbitTemplate.convertAndSend("exchang.direct","user.1",map);
}
//接受消息
@Test
public void receive(){
Object queue1 = rabbitTemplate.receiveAndConvert("queue1");
System.out.println(queue1.getClass());
System.out.println(queue1);
}
配置默认消息序列化
@Configuration
public class MyRabbitMQConfig {
@Bean
public MessageConverter messageConverter(){
return new Jackson2JsonMessageConverter();
}
}