什么是消息队列
MQ全称为Message Queue,消息队列是应用程序和应用程序之间的通信
- 为什么使用MQ
在项目中,可以将一些无需即使返回且耗时的操作提取出来,进行异步处理,而这种异步处理的方式大大的节省了服务器的请求响应时间,从而提高了系统的吞吐量 - 消息队列常用的应用场景
- 任务异步处理
将不需要同步处理且耗时的操作由消息队列通知消息接收方进行异步处理,提高了应用程序的响应时间 - 应用程序解耦合
MQ相当于一个中介,生产方通过MQ与消费放交互,它将应用程序进行解耦合 - 削峰填谷
如订单系统,在下单的时候就会往数据库中写数据,但是数据库只能支撑每秒1000左右的并发写入,并发量在高就容易死机,低峰期的时候并发也就100多个,但是在高峰期的时候,并发量会突然激增到5000以上,这个时候数据库肯定就会卡死
案例
消息被MQ保存起来,然后系统就会按照自己的消费能力消费,比如每秒1000个数据,这样慢慢写入数据,数据库就不会卡死
但是使用了MQ之后。限制消费消息的速度为1000,但是这样一来,高峰期生产的数据势必会被积压在MQ中,高峰就被削掉了,但是因为消息积压,在高峰期过后的一段时间内,消费消息的速度还是会维持在1000QPS,知道消费完积压的消息,这就叫做填古
AMQP和JMS
AMQP是一种协议,更准确的说是一种binary wire-level protocol(链接协议).这是其和JMS的本质差别,AMQP不从API层进行限定,而是直接定义网络交换的数据格式
JMS
JMS集java消息服务(Java message service)应用程序接口,是一个java平台关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信
AMQP与JMS的区别
- JMS是定义了统一的接口。来对消息操作进行统一,AMQP是通过规定协议来统一数据进行交互的格式
- JMS限定了必须使用java语言;AMQP只是协议,不规定时限方式,因此是跨语言的
- JMS规定了两种消息模式;而AMQP的消息模式更加丰富
RabbitMq
RabbitMq是使用Erlang语言编写实现了AMQP(Advanced Message Queuing Protocol)高级消息队列协议的消息队列服务
RabbitMq原理图
RabbitMq基本组件介绍
- Message:消息,由消息头和消息体组成。消息体是不透明的,消息头有一些可选属性组成,包括:routing-key(路由键),priority(优先级),delivery-mode(消息是否可持久化存储)
- Publisher:消息的生产者,也是由一个向交换机发布消息的客户端应用程序
- Consumer:消息的消费者,从一个消息队列中取得消息的客服端应用程序
- Exchange:交换机,用来接收生产发送的消息,并将这些消息路由给服务器中的队列,三种常见的交换器:direct(发布与订阅,完全匹配),fanout(广播),topic(主题,规则匹配)
- Binding:绑定,用于消息队列和交换器之间的关联,一个绑定就是由路由键将交换机和消息队列绑定的路由规则,所以可以将交互机理解成一个由绑定构成的路由表
- Queue:消息队列,用来保存消息并被消费者消费,消息被消费后将移除队列
- Routing-key:路由键,RabbitMQ决定消息该投递到哪个队列的规则。队列通过路由键绑定到交换器。消息发送到MQ服务器时,消息拥有一个路由键,即便是空的,RabbitMQ也会将其和绑定使用的路由键进行匹配。如果相匹配,消息会投递到该队列,如果不匹配,消息将会进入黑洞。
- Connection:RabbitMq服务器和服务建立的TCP连接
- Channel:信道,多路复用连接中的一条独立的双向数据流通道,为会话提供物理传输介质
- Virtual Host:虚拟主机,表示一批交换机,消息队列和相关对象。虚拟主机是共享相同的身份认证和加密环境的独立服务器。
- Broker:消息中间件的服务结点,一般情况下可以将一个RabbitMq Boker看做一台RabbitMq服务器
RabbitMq运转过程
- 生产者发送消息
生产者创建连接,开启一个频道,连接到RabbitMq Broker
声明队列并设置属性,例如是否排他,持久化,自动删除
将路由键(空字符串)与队列绑定起来
发送消息到RabbitMq Broker
关闭频道
关闭连接 - 消费者接受消息
消费者创建连接,开启频道,连接到RabbitMq Broker
想Broker请求消费相应队列中的消息,设置相应的回调函数
等待Broker回应闭关投递响应队列中的消息,消费者接受消息
确认(自动确认)接收到消息
RabbitMq从队列中删除已被确认的消息
关闭频道
关闭连接