什么是MQ
mq(message queue):面向消息的中间件(message-oriented middleware)是指利用高效可靠的消息传递机制与平台无关的数据交流,并基于数据通信来进行分布式系统的集成。
通过提供消息传递和消息排队模型在分布式环境下提供应用解耦,弹性伸缩,冗余存储、流量削峰,异步通信,数据同步等功能。
发送者把消息发送给消息服务器,消息服务器将消息存放在若干队列/主题topic中,在合适的时候,消息服务器回将消息转发给接受者。在这个过程中,发送和接收是异步的,也就是发送无需等待,而且发送者和接受者的生命周期也没有必然的关系;尤其在发布pub/订阅sub模式下,也可以完成一对多的通信,即让一个消息有多个接受者。
MQ产品分类
- Kafka:最初由Linkedin公司开发,是一个分布式、分区的、多副本的、多订阅者,基于zookeeper协调的分布式日志系统(也可以当做MQ系统),常见可以用于web/nginx日志、访问日志,消息服务等等,Linkedin于2010年贡献给了Apache基金会并成为顶级开源项目。
- RabbitMQ:实现了高级消息队列协议(AMQP)的开源消息代理软件(亦称面向消息的中间件)。RabbitMQ服务器是用Erlang语言编写的,而集群和故障转移是构建在开放电信平台框架上的。所有主要的编程语言均有与代理接口通讯的客户端库。
- RocketMQ:RocketMQ是一款分布式消息中间件,最初是由阿里巴巴消息中间件团队研发并大规模应用于生产系统,满足线上海量消息堆积的需求, 在2016年底捐赠给Apache开源基金会成为孵化项目,经过不到一年时间正式成为了Apache顶级项目;早期阿里曾经基于ActiveMQ研发消息系统, 随着业务消息的规模增大,瓶颈逐渐显现,后来也考虑过Kafka,但因为在低延迟和高可靠性方面没有选择,最后才自主研发了RocketMQ, 各方面的性能都比目前已有的消息队列要好,RocketMQ和Kafka在概念和原理上都非常相似,所以也经常被拿来对比;RocketMQ默认采用长轮询的拉模式, 单机支持千万级别的消息堆积,可以非常好的应用在海量消息系统中。
- ActiveMQ:Apache ActiveMQ是Apache软件基金会所研发的开放源代码消息中间件;由于ActiveMQ是一个纯Java程序,因此只需要操作系统支持Java虚拟机,ActiveMQ便可执行。
MQ技术维度(共性)
- api发送和接受
- 高可用性
- 集群和容错配置
- 持久化
- 延时发送/定时投送
- 签收机制
为什么需要MQ
引入MQ之前我们碰到的问题
1、 系统之间接口耦合比较严重;
每新增一个下游功能,都要对上游的相关接口进行改造;
举个例子:如果系统A要发送数据给系统B和系统C,发送给每个系统的数据可能有差异,因此系统A对要发送给每个系统的数据进行了组装,然后逐一发送;
当代码上线后又新增了一个需求:
把数据也发送给D,新上了一个D系统也要接受A系统的数据,此时就需要修改A系统,让他感知到D系统的存在,同时把数据处理好再给D。在这个过程你会看到,每接入一个下游系统,都要对系统A进行代码改造,开发联调的效率很低。其整体架构如下图:
2、 面对大流量并发时,服务器容易被冲垮;
每个接口模块的吞吐能力是有限的,这个上限能力如果是堤坝,当大流量(洪水)来临时,容易被冲垮。
举个例子秒杀业务:
上游系统发起下单购买操作,我就是下单一个操作
下游系统完成秒杀业务逻辑
(读取订单,库存检查,库存冻结,余额 检查,余额冻结,订单生产,余额扣减,库存减少,生成流水,余额解冻,库存解冻)
3、 等待同步存在性能问题;
RPC接口上基本都是同步调用,整体的服务性能遵循“木桶理论”,即整体系统的耗时取决于链路中最慢的那个接口。
比如A调用B/C/D都是50ms,但此时B又调用了B1,花费2000ms,那么直接就拖累了整个服务性能。
引入MQ之后能解决我们以上的问题
1、 要做到系统解耦,当新的模块接进来时,可以做到代码改动最小,能解耦;
2、 设置流量缓冲池,可以让后端系统按照自身吞吐能力进行消费,不被冲垮;能削峰;
3、 强弱依赖梳理能将非关键调用链路的操作异步化并提升整体系统的吞吐能力;能异步;
特点
1、 采用异步处理模式;
消息发送者可以发送一个消息而无须等待响应。消息发送者将消息发送到一条虚拟的通道(主题或者队列)上;
消息接收者则订阅或者监听该通道。一条消息可能最终转发给一个或者多个消息接收者,这些消息接收者都无需对消息发送者做出同步回应。整个过程都是异步的。
案例:
也就是说,一个系统跟另一个系统之间进行通信的时候,假如系统A希望发送一个消息给系统B,让他去处理。但是系统A不关注系统B到底怎么处理或者有没有处理好,所以系统A把消息发送给MQ,然后就不管这条消息的“死活了”,接着系统B从MQ里面消费出来处理即可。至于怎么处理,是否处理完毕,什么时候处理,都是系统B的事儿,与系统A无关。
这样的一种通信方式,就是所谓的“异步”通信方式,对于系统A来说,只需要把消息发送给MQ,然后系统B就会异步的去进行处理了,系统A不需要“同步”的等待系统B处理完成,实现了系统A和系统B 之间的解耦。
1、 应用系统之间解耦合;
发送者和接受者不必了解对方,只需要消息确认。
发送者和接受不必同时在线,也不必像微服务那种,需要提供者服务和消费者服务在注册中心中存活才能正常通信。
用户支付了一笔订单后,订单系统将消息发送到消息系统(MQ),而仓库系统从消息系统中获取消息之后完成发货和配送操作。在此期间,订单系统不必等待仓库系统是否在线才把消息发送出去,而仓库系统从消息系统获取消息时候,订单系统不必实时等待仓库系统的响应。