世界将我包围 誓死都一齐
壮观得有如 悬崖的婚礼
概述
消息队列,简称MQ(Message Queue), 目的是为了提升系统的异步通讯、扩展解耦能力java
- 如注册为列子,通常注册成功后会发送一条消息给用户,若是当咱们将数据保存成功后,继续执行发送消息的逻辑,这时候系统就是在等待发送逻辑运行,会下降系统的速度;其实注册成功后发送消息不是要当即响应成功的,咱们能够注册成功后,将要发送的消息放入消息队列,而后发送消息的逻辑代码根据消息队列信息去执行,便提升了系统的运行速度
- 还应用在订单系统的应用解耦,秒杀系统的流量削峰
两种形式
- 队列(queue):点对点消息通讯
- 主题(topic):发布(publish)/订阅(subscribe)消息通讯
点对点式:
- 消息发送者发送消息,消息代码将其放入一个队列中,消息接受者从队列获取消息,消息读取后移出队列
- 消息只有惟一的发送者和接受者,但不是只有一个接收者,即A、B、C都接收到了这个消息,但是消息被A所接受了,B、C接收到了可是使用不了
订阅式:
- 发送者发送消息到主题,多个接受者监听订阅这个主题,那么消息在到达的同时收到消息
JMS和AMQP
- JMS(Java Message Service),JAVA消息服务,是一个API;基于JVM消息代理的规范,ActiveMQ是JMS实现的
- AMQP(Advanced Message Queuing Protocol),是一个高级消息队列协议,兼容JMS,RabbitMQ是AMQP的实现

RabbitMQ简介
RabbitMQ从总体上来看是一个典型的生产者消费者模型,主要负责接收、存储和转发消息。
架构图以下:spring

Product,生产者
- 生产者链接到RabbitMQ Broker,创建一个链接( Connection)开启一个信道(Channel)
- 生产者声明一个交换器,并设置相关属性,好比交换机类型、是否持久化等
- 生产者声明一个队列井设置相关属性,好比是否排他、是否持久化、是否自动删除等
- 生产者经过路由键将交换器和队列绑定起来
- 生产者发送消息至RabbitMQ Broker,其中包含路由键、交换器等信息。
- 相应的交换器根据接收到的路由键查找相匹配的队列。
- 若是找到,则将从生产者发送过来的消息存入相应的队列中。
- 若是没有找到,则根据生产者配置的属性选择丢弃仍是回退给生产者
- 关闭信道,关闭链接。
Exchange,交换器
在RabbitMQ中,生产者并不是直接将消息投递到队列中。真实状况是,生产者将消息发送到Exchange(交换器),由交换器根据路由规则将消息路由到一个或多个队列中。若是路由不到,或返回给生产者,或直接丢弃,或作其它处理。架构
RoutingKey,路由KEY
指定消息的路由规则,须要与交换器类型和绑定键(Binding)联合使用才能最终生效,在绑定的条件下,生产者能够在发送消息给交换器时经过指定RoutingKey来决定消息流向哪一个消息队列。异步
Binding
将交换器和队列关联起来,决定交换器的消息发送到哪一个队列上性能
Queue,队列
- RabbitMQ的内部对象,用于存储消息
- 生产者投递消息到队列,消费者从队列中获取消息并消费
- 多个消费者能够订阅同一个队列,这时队列中的消息会被平均分摊(轮询)给多个消费者进行消费,而不是每一个消费者都收到全部的消息进行消费
RabbitMQ四种类型的交换器
direct交换器,fanout交换器,topic交换器,headers交换器ui
direct交换器
把消息路由到RoutingKey与BindingKey彻底匹配的队列中,是彻底匹配、单播的形式spa
- eg:若是路由键为“java”,则只能转发RoutingKey为“java”的消息到绑定的队列中去,不会转发如“java.spring”
fanout交换器
会把发送到该交换器的消息路由到全部与该交换器绑定的队列中,不会匹配路由Key,转发消息是最快的代理
topic交换器
经过模式匹配分配消息,将路由键和某个模式进行匹配,识别两个通配符:“#”和“”。#匹配0个或多个单词,匹配一个单词code
- eg:发送一条消息,RoutingKey为“java.spring”,这时候会匹配到RoutingKey为“java.#”和“#.spring”的队列
headers交换器
不依赖于路由键的匹配规则来路由消息,而是根据发送的消息内容中的headers 属性进行匹配。该交换器类型性能较差且不实用,所以通常不会用到对象