查看原文
其他

白话讲解:消息队列到底解决了什么问题?

博文视点 博文视点Broadview 2020-11-06



2020年处于移动互联网的下半场,各种技术层出不穷,虽然数据也在爆发式增长,但是高并发、高吞吐已经不再是首要的痛点,稳定、可靠才是王道。

本文作为一篇消息队列入门级介绍,帮助大家对消息队列有一个大致的了解,并对对时下流行的消息队列组件进行了简单的比较,供大家做技术选型的参考。


1  什么是消息队列


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


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

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

下面我们以春节订火车票为例进行说明,流程如下。

拿到年终奖了,准备买车票带着媳妇儿回家过年。你打开12306手机App开始做如下操作:

第一步:输入车票信息,发送订票请求。

起点站:北京。

终点站:成都。

出发时间:腊月29晚上8点。

票数:2张。

座席:硬卧。

第二步:单击“预订”按钮,12306 App界面开始转圈圈。与此同时全国3亿人民也在和你一起做相同的事情。

第三步:3s后,应用告诉你订票失败。

第四步:你修改车次,重新发送订票请求。应用重复第二步继续等待。又一个3s后,12306 App告诉你订票成功。


12306 App在处理上图逻辑时,会遇到以下挑战:

(1)今天这个车次只售出4000张票,而实际有30万人发送了订票信息,如果逐一请求处理,那么90%以上的人都将要耗时3s来等待,怎么办?

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

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

以上只是随机列举了一些常见的问题,如何才能优雅地处理呢?

答案是:消息队列!


2  为什么需要消息队列


我们平时什么时候可能会用到消息队列呢?下面结合刚才的流程图来介绍消息队列的适用场景。

削峰填谷 

业务系统在超高并发场景中,由于后端服务来不及同步处理过多、过快的请求,可能导致请求堵塞,严重时可能由于高负荷拖垮Web服务器。

我们都希望流量如上图虚线部分一样一直比较平稳,这样我们的系统也会更加稳定。但是实际的流量会随着时间不短变化,像12306 App这样的App流量大得难以想象,而一年中不同的时间段,其流量也不同。为了能支持最高峰流量,我们通常采取短平快的方式——直接扩容服务器,增加服务端的吞吐量。

优点是显而易见的,短时间内吞吐量增加了好几倍,甚至数十倍。缺点也明显,流量低峰期服务器相对较闲。

如何平衡平时的空闲与节假日的超高峰呢?我们想到了消息队列(比如Apache RocketMQ,Apache Kafka),也是目前业界比较常用的手段。利用消息队列扭转处理订票请求,告知用户30min内会告诉他/她订票结果。优缺点明显:性能提升了,但是我们作为业务开发人员,还要维护一个消息队列服务,人手完全不够。消息中间件呼之欲出。

程序间解耦 

不同的业务端在联合开发功能时,常常由于排期不同、人员调配不方便等原因导致项目延期。其实,其根本原因是业务耦合过度。

下图中,上下游系统之间的通信是彼此依赖的,所以不得不协调上下游所有的资源同步进行,跨团队处理问题显然比在团队内部处理问题难度大。


你是否依稀记得另一个团队的同事调用你的API,你告诉他发个请求过来,你打断点一步一步调试代码的场景?

你是否记得为了协调开发资源、QA资源,以及协调上线时间等所做的一切,你被老板骂了多少次,最后还是延期了:我们依赖他们,他们的QA说,高峰期不让发布。

加入消息队列后,不同的业务端又会是何种情况呢?


上下游系统进行开发、联调、上线,彼此完全不依赖,也就是说,系统间解耦了。

异步处理 

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

数据的最终一致性 

我们举例说明。很怀念每月的1号,可以向老婆的“财务部”缴费了。你的工资在招商银行,你老婆的工资在北京银行。通常,两个系统的通信过程如下。


如果通信失败,怎么保证你的钱“上交”了呢?业内常用的手段就是消息队列。消息系统的优点:

(1)免去了招商银行App多次重试(发起请求)的复杂逻辑。(2)免去了北京银行App处理过多重试请求的压力。

(3)即使北京银行服务不可用,业务也不受影响。


3  常见消息队列


这里对时下流行的消息队列组件进行了简单的比较,供大家做技术选型的参考。

消息队列名字

Apache ActiveMQ

Apache Kafka

Apache RocketMQ

Apahe Pulsar

产生时间

2007

2012

2017

2018

贡献公司

Apache

LinkedIn

阿里巴巴

雅虎

当时流行MQ

JMS

ActiveMQ

Kafka,ActiveMQ

RocketMQ,Kafka

特性

(1)支持协议众多:AMQP,STOMP,MQTT,JMS

(2)消息是持久化的JDBC

(1)超高写入速率

(2)end-to-end耗时毫秒级

(1)万亿级消息支持

(2)万级Topic数量支持

(3)end-to-end耗时毫秒级

(1)存储计算分离

(2)支持SQL数据查询

管理后台

自带

独立部署

独立部署

多语言客户端

支持

支持

Java

C++

Python

Go

C#

Java

C++

Python

Go

数据流支持

不支持

支持

支持

支持

消息丢失

理论上不会丢失

理论上不会丢失

理论上不会丢失

理论上不会丢失

文档完备性

极好

极好

社区不断完善中

商业公司实践

国内部分企业

LinkedIn

阿里巴巴

雅虎、腾讯、智联招聘

容错

无重试机制

无重试机制

支持重试,死信消息

支持重试、死信消息

顺序消息

支持

支持

支持

支持

定时消息

不支持

不支持

支持

支持

事务消息

不支持

支持

支持

支持

消息轨迹

不支持

不支持

支持

自己实现简单

消息查询

数据库中查询

不支持

支持

支持SQL

重放消息

不清楚

暂停重放

实时重放

支持

宕机

自动切换

自动选主

手动重启

自动切换

Apache RocketMQ是一款开源的、分布式的消息投递与流数据平台。出生自阿里巴巴,经历了近十年双11核心交易链路打磨,可以支撑万亿级消息洪峰。

作为Apache顶级开源项目之一,其在GitHub上有10000+ star、5000+ fork、170+ contributors(在GitHub上提交代码并被采纳的开发者),目前中国互联网、金融等行业Top级企业75%以上都在使用,已经成为云原生时代企业上云的核心基础设施!

学习掌握Apache RocketMQ,博文菌强烈推荐《RocketMQ分布式消息中间件:核心原理与最佳实践》一书。

李伟 著

作者有多年分布式系统的实战经验,特别是在消息队列方面经验丰富。本书根据作者在项目中使用RocketMQ的实际经验,结合实际源码,由浅入深地讲解了RocketMQ核心功能的具体实现逻辑,并从消息队列的应用场景出发,使读者快速地了解MQ解决的问题域。

通过阅读本书,不仅可以了解如何在项目中使用消息队列,还能学习到RocketMQ的实现细节,进一步提升对RocketMQ系统本身的把控力度。

▼扫码了解本书详情▼


▼ 加入本书交流群,共同学习 ▼



如果喜欢本文欢迎 在看留言分享至朋友圈 三连

 热文推荐  





点击阅读原文,了解本书详情~

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存