RabbitMQ学习笔记
RabbitMQ学习笔记
什么是MQ
消息队列(message queue),本质是个存放消息的队列,先进先出(FIFO),主要用于不同进程/线程间的通讯。
为什么使用MQ?
- 异步处理
- 流量削峰
- 组件解耦
- 流量缓冲:比如下单量暴增,即使数据库读写分离,也会导致写节点可能挂逼,出现丢单之类的高风险事件,这时订单信息先打到MQ,然后在消费MQ里的信息处理DB。
写多读少用队列,读多写少用缓存。
RabbitMQ
RabbitMQ简介
- 消息队列是应用与应用之间通讯的一种方式。
- RabbitMQ是一个在AMQP基础上完整的可复用的开源的企业消息系统。
- 支持多平台、多语言。
- 开发语言:Erlang
AMQP
AMQP(高级消息队列协议)是消息队列的一种协议,是一个进程间传递异步消息的网络协议。
生产者 --> Broker --> vhost --> exchange(根据不同的规则匹配到对应的消息队列) --> message queue
消费者监听消息队列 --> message queue
特点
- 性能高
- 提供了可靠性消息的投递和返回模式,相比kafka,可靠性投递更高
- 在客户端签收方面也做了处理
- 集群模式比较丰富:表达式配置,HA模式,镜像队列模型
RabbitMQ如何实现高性能
- Erlang语言最开始使用在交换机领域,这样使得RabbitMQ与Broker之间进行数据交互的性能非常高。
- Erlang有着与原生Socket一样的延迟。
- 因为Java自动垃圾回收机制会导致GC工作时工作线程暂停。所以Erlang相对于Java,性能更高一些。
核心名词
- Broker: 相当于AMQP实体服务,接受客户端的连接。
- connection:客户端连接到Broker的网络连接。
- channel:网络信道,几乎所有操作都是在channel中进行,所有数据的流转都在channel。他是进行读写的通道,客户端可以建立多个channel,每一个channel代表一个会话任务。与NIO的channel类似。
- message:消息,Broker与应用之间传输的数据。有properties和body组成。properties中包含消息的属性(优先级、延迟等信息)。body就是消息的内容。
- vhost:虚拟主机,用于进行逻辑隔离,是最上层的消息路由,一个vhost里面可以有多各exchange(交换机)和消息队列。
- exchange:交换机,接受消息,根据路由键转发消息到具体的消息队列当中。
- binding:绑定。交换机与消息队列的虚拟连接。 绑定中可以包含routing key,维护exchange与消息队列的绑定关系。
- routing key:路由规则。exchange用它来确定将消息转发到哪一个消息队列。
- message queue:消息队列,保存信息并将它转发给消费者。
消息流转图
JavaAPI相关类与API解释
- connectionFactory:获取连接的工厂。
- connection:一个客户端与server的连接。
- channel:数据通信信道。可以发送和接受消息。
- queue:具体的消息存储队列。
- queuingConsumer:消息队列的消费者。
- delivery:MQ对消息和channel的java封装。
交换机详解
常见属性解释
- name:交换机名
- type:交换机类型(direct、fanout、headers、topic),表示路由策略。
- durability:是否持久化,表示这个交换机在服务重启后是否还存在。
- auto delete:是否自动删除,当交换机对应的所有消息队列都不存在时,是否自动删除。
- internal:当前交换机是否用于rabbitMQ内部使用。默认为false。表示是否可以用erlang编程语言直接使用。false表示可以使用。true的话只能在rabbitMQ内部使用。
- arguments:交换机可扩展参数。用户自定义交换机时,用到的参数。
交换机类型(对应type属性)
- direct:
- 生产者生产的消息的routingKey与消息队列的routingKey一致时,该消息就会被转发到这个消息队列当中。
- default exchange是direct exchange。
- topic:
- routingKey可以使用通配符,#表示任意多个单词(.分割),*表示任意单个单词(.分割),生产者的消息的routingKey与消息队列的routingKey可以匹配的时候,则被投递。
- 如果有多个消息队列的bindingKey规则都符合,则多routingKey个消息队列都会被投递。
- fanout:
- 没有路由键(routingKey),只需要简单的将队列绑定到交换机上。
- 发送到交换机的消息会被转发到所有与交换机绑定的队列上。
- fanout交换机转发消息最快。
- headers: 基本不用。