消息队列简介

目录

什么是消息队列

为什么需要消息队列

1.削峰填谷

2.程序间解耦

3.异步处理

4.数据的最终一致性

常见的消息队列

RocketMQ 的发展史


什么是消息队列

消息队列(Message Queue),从广义上来讲是一种消息队列服务的中间件,提供一套完整的信息生产、传递、消费的软件系统。

消息队列所涵盖的功能远不止于队列,其本质是两个进程传递信息的一种方法。两个进程可以分布在同一台机器上,亦可以分布在不同的机器上。

众所周知,进程可以通过 RPC(Remote Procedure Call,远程过程调用)进行,那么我们为什么要用消息队列这种软件服务来传递消息呢?

以 12306 手机 APP 为例,订票的操作流程为:

第一步:输入车票信息,起点站、终点站、座席等信息,发送订票请求;

第二步:提交订单,之后等待,此时 APP 界面会出现转圈,意味着你正在和其他人进行抢票;

第三步:3s 或更短时间内短信告知你是否购票成功。

那么 12306 在处理如上订票的过程中会遇到以下问题:

(1)如果今天这个车次只能出售 2000 张票,而实际却有超过 20 万人提交了购票信息,如果逐一请求处理,那么可能将有超过 90% 的人需要耗时大约 3s 来等待,这种情况怎么处理?

(2)如果下游有 20 个系统需要在订票成功之后进行通知,如果逐一调用这些接口进行通知,而如果其中一个系统的通知任务执行失败,那么通知成功的任务会怎样?

(3)12306 的架构会不断调整,当数据结构发生变化时,下游 20 个系统都要随着一起变化吗?

为了处理这些问题,最好的方法就是使用消息队列。

为什么需要消息队列

1.削峰填谷

业务系统在超高并发场景中,由于后端服务来不及同步吃力过多过快的请求,可能导致请求堵塞,严重时可能会由于高负荷拖垮服务器。其实我们都希望流量能够像一条直线一样一直比较平稳,这样我们的系统也会更加稳定。但是实际的流量会随着时间而不断变化,像 12306 这种的 APP,有时候流量大到难以想象,而一年中不同的时间段,其流量大小也不同,有高峰期,也有低谷期。为了能支持最高峰的流量,我们通过采用短平快的方式——直接扩容服务器,来增加服务端的吞吐量。优点是显而易见的,短时间内服务器的吞吐量增加了好几倍,甚至是数十倍。缺点也很明显,流量低峰期时服务器相对较闲。那么如何平衡平时的空闲与节假日的超高峰呢?消息队列便是目前业界比较常用的手段。利用消息队列扭转处理订票请求,告知用户 30min 内会告知订票结果。优缺点也很明显,性能有了明显的提升,但是我们作为业务开发人员,还要维护一个消息队列服务,人手便有些不足。

2.程序间解耦

不同的业务端在联合开发功能时,常常由于排期不同、人员调配不方便等原因导致项目延期。这中间最根本的原因是业务耦合过度。即上下游系统之间的通信是彼此依赖的,所以不得不协调上下游所有的资源同步进行,跨团队处理问题显然比在团队内部处理问题的难度要大。

加入消息队列之后,上下游系统进行开发、联调、测试时完全不依赖,大大降低了系统间的耦合度。

3.异步处理

处理订票请求是一个漫长的过程,需要检查预订的车次是否有足够数量的余票、下单扣减库存、更新缓存、调用三方短信等一系列操作。这些耗时的操作我们可以通过消息队列的方式,把请求提交成功的消息告诉用户,然后异步处理这些耗时的操作,保证 30min 能能把处理的结果通过短信推送给用户,否则系统处理多久,用户就得等多久。

4.数据的最终一致性

举例来说,我需要将我 A 银行卡上的钱转 1000 块到 B 银行卡,那么正常的处理流程就是我先在 A 银行的 APP 上提交转账请求,然后 A 银行卡扣除我 1000 块的账户余额,之后 B 银行卡会增加我 1000 块的账户余额,那么如果在这个过程当中通信失败的话,我就无法直到我的钱到底是被扣了还是没有被扣。此时就需要消息队列了。即,我在 A 银行的 APP 上提交转账请求之后,A 银行的后端服务会立即扣除我 1000 块的账户余额,并通知我说转账请求发送成功之类的消息。之后 A 银行会通过消息队列来通知 B 银行给我的账户余额增加 1000 块,处理完成之后会通过短信告诉我转账已成功。那么此时消息队列使用的优点便是:

(1)免去了 A 银行的重试机制的复杂逻辑,即 A 银行不需要多次去请求并等待 B 银行的处理结果,只需要告诉 B 银行这个消息即可;

(2)免去了 B 银行多次处理 A 银行请求的压力;

(3)即使 B 银行的服务器不可用,也不影响我在 A 银行提交转账申请。

常见的消息队列

常见的消息队列
消息队列名称Apache ActiveMQApache KafkaApache RocketMQApache Pulsar
产生时间2007201220172018
贡献公司ApacheLinkedIn阿里巴巴雅虎
特性支持协议众多:AMQP、STOMP、MQTT、JMS;
消息是持久化的JDBC
超高写入速率;
end-to-end 耗时毫秒级
万亿级消息支持;
万级 Topic 数量支持;
end-to-end 耗时毫秒级
存储计算分离;
支持 SQL 数据查询
管理后台自带独立部署独立部署
多语言客户端支持支持Java、C++、Python、Go、C#Java、C++、Python、Go
数据流支持不支持支持支持支持
消息丢失理论上不会丢失理论上不会丢失理论上不会丢失理论上不会丢失
文档完备性极好极好社区完善 中
商业公司实践国内部分企业LinkedIn阿里巴巴雅虎、腾讯、智联招聘
容错无重试机制无重试机制支持重试与死信消息支持重试与死信消息
顺序消息支持支持支持支持
定时消息不支持不支持支持支持
事务消息不支持支持支持支持
消息轨迹不支持不支持支持自己实现简单
消息查询数据库中查询不支持支持支持 SQL
重放消息未知暂停重放实时重放支持
宕机自动切换自动选主手动重启自动切换

RocketMQ 的发展史

和大部分组件产生的原因类似,阿里巴巴内部为了适应淘宝 B2C 的更快、更复杂的业务,2001 年启动了“五彩石项目”,阿里巴巴的第一代消息队列服务 Notify 就是在这个背景下产生的。2010 年,阿里巴巴内部的 Apache ActiveMQ 仍然作为核心技术被广泛应用于各个业务线,而顺序消息、海量消息堆积、完全自主控制消息队列服务,也是阿里巴巴同时期急需的,在这种背景下,2011 年,MetaQ 产生。

2011 年,LinkedIn 将 Kafka 开源。2012 年,阿里巴巴参考 Kafka 的设计,基于对 MetaQ 的理解和实际应用,研发了一套通用消息队列引擎,也就是 rocketMQ 。自此才有了第一代真正的 RocketMQ,2016 年阿里云上线 RocketMQ 消息队列服务。自 2001 年到 2012 年,11 年的实际使用、运维,和业务不断碰撞,才得以抽象并整理出一个真正的行业级产品。

2016 年 11 月,阿里巴巴将 RocketMQ 捐献给 Apache 基金会。Apache 社区有一个很重要的概念:社区大于代码。虽然 RocketMQ 已经开源 3 年,在国内小有名气,而且在阿里巴巴被广泛应用并有较好的效果,但是依然不能达到 Apache 优秀项目的标准。在 RocketMQ 被捐献后,通过一系列的修改、评审、调整,悄悄升级至 4.0 版本,正式进入孵化阶段。2017 年 9 月 25 日,RocketMQ 成功毕业,即 Apache 社区项目孵化成功。成为 Apache 顶级项目 ,它是国内首个互联网中间件在 Apache 的顶级项目,也是继 ActiveMQ、Kafka 后 Apache 家族中全新的一代消息队列引擎。

RocketMQ 主要由 Producer、Broker、Consumer 三部分组成,其中 Producer 负责生产消息,Consumer 负责消费消息,Broker 负责存储消息。Broker 在实际部署过程中对应一台服务器,每个 Broker 可以存储多个Topic 的消息,每个 Topic 的消息也可以分片存储于不同的 Broker。Message Queue 用于存储消息的物理地址,每个 Topic 中的消息地址存储于多个 Message Queue 中。ConsumerGroup 由多个 Consumer 实例构成。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值