文章目录
一文读懂MQ
理解MQ
1 提供的能力
1.1 解耦
- 服务关系复杂化、导致系统架构犹如蜘蛛网,服务关系难以理解
- 功能维护复杂化
- eg:A 系统发送数据到 BCD 三个系统,通过接口调用发送。如果 E 系统也要这个数据呢?那如果 C 系统现在不需要了呢?A系统都要做出相应调整
- 通过一个 Pub/Sub 发布订阅消息这么一个模型,A 系统就跟其它系统彻底解耦了(非同步调用的case)
1.2 异步化
- eg:A 系统接收一个请求,需要在自己本地写库,还需要在 BCD 三个系统写库,自己本地写库要 3ms,BCD 三个系统分别写库要 300ms、450ms、200ms。最终请求总延时是 3 + 300 + 450 + 200 = 953ms
使用 MQ,那么 A 系统连续发送 3 条消息到 MQ 队列中,假如耗时 5ms,A 系统从接受一个请求到返回响应给用户,总时长是 3 + 5 = 8ms
1.3 消峰
- 系统平时的qps较低,在某个时间点的qps很高且超出短板服务的承受能力,导致服务不可用,盲目的扩增机器来撑qps会导致高峰期后硬件资源的浪费
- 利用mq可以使系统平稳的度过高峰期,即使是同步请求功能,也可以通过产品设计达到这种目的(例如淘宝双11和京东618)
2. 带来的问题:
- 运维成本增加:多了一个mq组件需要维护
- 系统可用性降低:对于分布式系统,多一个分布式组件,系统的可用性就会多承受一份威胁
- 系统复杂性提高:从系统架构上来说多了一个组件,对于开发人员来说也需要掌握更多的技能
- 一致性问题:例如异步化的场景,会出现数据一致性的问题,开发人员需要考虑这种场景进行开发
3. 协议:
3.1 JAVA API 之 JMS
- 简介:JMS是由Sun公司早期提出的消息标准,旨在为java应用提供统一的消息操作,包括create、send、receive;从使用角度看,JMS和JDBC担任差不多的角色,用户都是根据相应的接口可以和实现了JMS的服务进行通信,进行相关的操作;activeMQ就是基于该协议
- 消息模型:peer-2-peer(点对点);publish-subscribe(发布订阅)模型
- 路由机制:
- 由message-routing来决定。在JMS中,消息路由非常简单
- JMSconsumer同时支持message selector(消息选择器),通过消息选择器,consumer可以只消费那些通过了selector筛选的消息
3.2 AMQP(mq协议)
- 简介:AMQP(高级消息队列协议)是一个网络协议。它支持符合要求的客户端应用(application)和消息中间件代理(messaging middleware broker)之间进行通信;
- 语言支持:作为协议(类似于http),故本身支持所有语言;例如通过java客户端发送消息,通过ruby消费端进行消费
- 模型:
rabbitMQ
1 参考文献
2 基本属性
- 语言:Erlang,Erlang语言天生具备分布式特性(通过同步Erlang集群各节点的magic cookie来实现),天然支持集群模式(Clustering)
- **关键名词:**producer、broker、exchange、queue、channel、consumer
- 消费模型:支持pull和push两种模型;spring中是对push的封装**(kafka只支持pull模型)**
- 延时消息的方案
- 利用死信交换机&队列__dead-letter-exchange
- 建立一个有过期时间的queue(ttl)
- 无消费者,消息过期后进入死信队列
- 消费死信队列,则实现过期时间的延迟消息
- 利用插件:rabbitmq-delayed-message-exchange
- 利用死信交换机&队列__dead-letter-exchange
3 工作模型
- 直连dircet
- 主题topic
- 广播Fanout
4 消息可靠性
- producer -> Exchange
- 利用mq的ack机制保证exchange必然接收到message
- Exchange -> Queue
- rabbitmq提供了returnListien接口,实现该接口可以得到message是否正常进入queue
- queue -> consumer
- consumer客户端提供了消息确认机制
- consumer未确认接收到消息,则queue不会删除该消息
- 默认客户端接收到即确认
- 可以通过设置配置,来确保正常业务处理完成后再确认
5 服务高可用
-
Erlang语言天生具备分布式特性(通过同步Erlang集群各节点的magic cookie来实现),天然支持集群模式(Clustering)
-
各集群仅相互同步元数据,来保证数据一致性
-
具体暂不描述
kafka
1 参考文献
2 基本属性
- 关键名词:producer、broker、topic、partition、replicas、consumer、offset、leader、follower
- 消费模型:仅支持pull
3 属性介绍
- **partition:**topic中的数据分割为一个或多个partition,以到达数据分布式存储
- **replicas:**副本是分区的备份。副本不会被消费者消费,副本只用于防止数据丢失。副本间是一主多从关系
- **offset:**记录消费到哪里的偏移量
- **leader/follower:**一个partition下副本是一主多从的关系,主则为leader,其他为follower
3 分片模型
4 重点知识
- leader容灾:指副本的leader,服务端会在Zookeeper的/brokers/ids节点上注册Watch,一旦有broker宕机,则会从副本中选取一个作为leader
- **多副本同步:**由生产者来决定,通过request.required.acks参数来设置数据的可靠性-
- 0:不关心broker是否处理成功,可能丢数据。
- 1:当写Leader成功后就返回,副本异步同步数据;副本数据可能丢失
- -1:所有机器同步成功,才能返回成功;强一致,不会丢数据。
- **消费:**订阅topic是以一个消费组来订阅的,一个消费组里面可以有多个消费者
- **注意:**一个partition,只能被消费组里的一个消费者消费;例如partition数为4,消费组中消费者共有5个,则其中有一个消费者无法消费(一旦注册便无法消费)
4 消息可靠性
- 由生产者来决定,通过request.required.acks参数来设置数据的可靠性-
- 0:不关心broker是否处理成功,可能丢数据。
- 1:当写Leader成功后就返回,副本异步同步数据;副本数据可能丢失
- -1:所有机器同步成功,才能返回成功;强一致,不会丢数据。
5 服务高可用
- 利用zk来保证集群中各节点的可靠性
- 利用partition做分布式存储,保证数据可靠性
- 利用副本来保证服务高可用
- 具体不做介绍
rocketmq
1 参考文献
2 基本概念
- 参考上述官网,中文介绍很详细
3. 技术架构
RocketMQ架构上主要分为四部分,如上图所示:
- **Producer:**消息发布的角色,支持分布式集群方式部署。Producer通过MQ的负载均衡模块选择相应的Broker集群队列进行消息投递,投递的过程支持快速失败并且低延迟。
- **Consumer:**消息消费的角色,支持分布式集群方式部署。支持以push推,pull拉两种模式对消息进行消费。同时也支持集群方式和广播方式的消费,它提供实时消息订阅机制,可以满足大多数用户的需求。
- **NameServer:**NameServer是一个非常简单的Topic路由注册中心,其角色类似Dubbo中的zookeeper,支持Broker的动态注册与发现。主要包括两个功能:Broker管理,NameServer接受Broker集群的注册信息并且保存下来作为路由信息的基本数据。然后提供心跳检测机制,检查Broker是否还存活;路由信息管理,每个NameServer将保存关于Broker集群的整个路由信息和用于客户端查询的队列信息。然后Producer和Conumser通过NameServer就可以知道整个Broker集群的路由信息,从而进行消息的投递和消费。NameServer通常也是集群的方式部署,各实例间相互不进行信息通讯。Broker是向每一台NameServer注册自己的路由信息,所以每一个NameServer实例上面都保存一份完整的路由信息。当某个NameServer因某种原因下线了,Broker仍然可以向其它NameServer同步其路由信息,Producer,Consumer仍然可以动态感知Broker的路由的信息。
- **BrokerServer:**Broker主要负责消息的存储、投递和查询以及服务高可用保证,为了实现这些功能,Broker包含了以下几个重要子模块。
- Remoting Module:整个Broker的实体,负责处理来自clients端的请求。
- Client Manager:负责管理客户端(Producer/Consumer)和维护Consumer的Topic订阅信息
- Store Service:提供方便简单的API接口处理消息存储到物理硬盘和查询功能。
- HA Service:高可用服务,提供Master Broker 和 Slave Broker之间的数据同步功能。
- Index Service:根据特定的Message key对投递到Broker的消息进行索引服务,以提供消息的快速查询。