一、要解决的问题
1.1 异步
分析: 需要根据场景来判断。若整体链路的逻辑中,某些逻辑是不需要强实时
的,滞后一段时间是允许的,同时又不会对用户带来不好的体验,那么可以使用MQ完成异步操作。
例如:秒杀场景,是有限资源,同时用户可以接受某些逻辑的延迟,比如生成订单,发送积分等逻辑
1.2 流量控制 - 削峰
分析: 服务器的资源是有限的,同时高峰流量不是一直持续的,且为了保护后端的服务不被打垮,因此,需要对后端服务进入的请求流量进行限制,提高了吞吐量。
缺点:
- 由于在网关层将请求放入了消息队列,整体的请求耗时将会变长,降低了用户的体验;
- 下游服务都需要将同步请求修改为异步请求,增加了系统的复杂度。
改进方案
:若能预估出秒杀服务的处理能力,可采用令牌桶策略,网关在调用秒杀服务之前,先获取令牌桶,获取不到,则直接拒绝请求,这样用户可以快速的得到秒杀结果。
1.3 解耦
实现服务之间的解耦。已电商的下单为例:
- 下单后,会调用支付服务发起支付请求;
- 下单后,会调用风控服务发起订单合法性的校验;
- 下单后,会调用数仓服务更新数据
如果后续增加新的下游服务,那么订单服务每次都需要调整接口,都需要适配接口,影响开发效率。因此,可以使用MQ来进行解耦。
其他的应用场景:
- 实现系统间的观察者模式;
- 可以将消息广播给大量的消费者
使用MQ带来的问题:
1. 会带来延迟问题;
2. 数据存在短时间内的不一致问题
3. 系统复杂度上升
二、主流技术解决方案
2.1 MQ选型的考虑因素
1. 是否开源。后续出现bug,可以通过修改源代码来进行解决
2. 社区是否活跃。出现bug,能够找到解决方案;
3. 生态兼容性。与主流技术栈的兼容性,若兼容性不好,则需要耗费精力去和技术栈进行融合。
4. 消息不丢失;
5. 高可用:支持集群模式,保证MQ时时可用
6. 性能。能够满足绝大多数场景的需求。
2.2 主流MQ
2.2.1 Rabbit MQ
特点:
- 开箱即用,非常轻量化;
- 支持非常
灵活的路由配置
,和其他消息队列不同的是,它在生产者(Producer)和队列(Queue)之间增加了一个Exchange模块,你可以理解为交换机;- 基于elang语言开发,底层是采用了AMQP协议。
- 可用性:基于主从架构
核心架构:
缺点:
- 消息堆积处理不好。RabbitMQ认为消息堆积是异常情况,因此大量消息堆积下,性能下降的厉害;
- 性能差。每秒钟仅能处理大概几万条消息;
- 语言壁垒高
2.2.2 RocketMQ
RocketMQ是阿里开源的消息中间件,它是一个开源的分布式消息传递和流式数据平台。总共有四大部分:NameServer,Broker,Producer,Consumer
。
NameServer
:用来管理brokers以及路由信息。broker服务器启动时会注册到NameServer上,并且两者之间保持心跳监测机制,以此来保证NameServer知道broker的存活状态。而且,每一台NameServer都存有全部的broker集群信息和生产者/消费者客户端的请求信息。Broker
:负责管理消息存储分发,主从数据同步,为消息建立索引,提供消息查询等能力。
优点:
- 每秒钟大概能处理几十万条消息
- 消息零丢失
- 高性能:毫秒级的时延
- 可用性:分布式架构
2.2.3 Kafka
最初设计的目的是处理海量的日志。整体架构图:
核心原理: 一个Kafka集群由多个Broker和一个ZK集群组成,Broker作为Kafka节点的服务器。同一个消息主题Topic由多个分区Partition组成,分区物理存储在Broker上。为了负载均衡,同一个Topic的多个分区存储在不同的Broker上;为了提高可靠性,每个分区在不同的Broker上会存在副本。Kafaka里的ZK主要有以下作用:
1. Broker注册:当Broker故障时能及时感知;
2. 元数据管理:存储Broker,Topic和Partitions的配置信息,能感知信息的变化;
3. 消费者组管理:维护消费者的订阅信息,偏移量等,实现负载均衡;
4. Leader选举:Kafka中的每个Partition分区都会有一个leader,zk可以负责leader的选举,确保在leader宕机后,集群可以快速选择新的leader进行服务。
Kafka的分区和RockerMQ的队列是类似的。
优缺点:
- 异步性能高。底层大量采用了批量和异步的思想;
- 时延:毫秒级
- 每秒钟可以处理几十万条消息;
- 生态兼容性好
- 同步收发消息响应时延高。底层原理:当Kafka接收到消息时,并不会立即发送出去,而是等一会攒一批再发送。因此,当每秒钟消息没有那么多时,等的时间就比较长,时延就很长,因此不适合在线业务场景。
2.2.4 pulsar
新兴的MQ产品,采用存储与计算分离的架构。
2.3 各种MQ适用场景
● 若对消息队列功能和性能要求不高,建议选择RabbitMQ,开箱即用且易于维护
● 若处理在线业务,建议选择RockMQ,低延迟和金融级的稳定性是非常nice的;
● 若处理海量消息,例如日志,监控或埋点信息,建议选择Kafaka。