为什么需要消息队列

削峰

业务系统在超高并发场景中,由于后端服务来不及同步处理过多、过快的请求,可能导致请求堵塞,严重时可能由于高负荷拖垮Web服务器。
为了能支持最高峰流量,我们通常采取短平快的方式——直接扩容服务器,增加服务端的吞吐量。
优点是显而易见的,短时间内吞吐量增加了好几倍,甚至数十倍。缺点也明显,流量低峰期服务器相对较闲。
消息队列(比如 Apache RocketMQ,Apache Kafka),也是目前业界比较常用的手段

解耦

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

你是否依稀记得另一个团队的同事调用你的API,你告诉他发个请求过来,你打断点一步一步调试代码的场景?
你是否记得为了协调开发资源、QA 资源,以及协调上线时间等所做的一切,你被老板骂了多少次,最后还是延期了:我们依赖他们,他们的QA说,高峰期不让发布。
加入消息队列后,不同的业务端又会是何种情况呢?上下游系统进行开发、联调、上线,彼此完全不依赖,也就是说,系统间解耦了
image

异步

处理订票请求是一个漫长的过程,需要检查预订的车次是否有预订数量的票、下单扣库存、更新缓存等一系列操作。这些耗时的操作,我们可以通过使用消息队列的方式,把提交请求成功的消息告诉用户

数据一致性

消息系统的优点:
(1)免去了多次重试(发起请求)的复杂逻辑。
(2)免去了处理过多重试请求的压力。
(3)即使服务不可用,业务也不受影响。

常见消息队列

消息队列名字 Apache ActiveMQ Apache Kafka Apache RocketMQ
产生时间 2007 2012 2017
贡献公司 Apache LinkedIn 阿里巴巴
当时流行MQ JMS ActiveMO Kafka,ActiveMO
特性 (1)支持协议众多:AMOP,STOMP,MOTT,JMS
(2)消息是持久化的JDBC
(1)超高写入速率
(2)end-to-end 耗时毫秒级
(1)万亿级消息支持
(2)万级Topic数量支持
(3)end-to-end耗时毫秒级
管理后台 自带 独立部署 独立部署
多语言客户端 支持 支持 Java、C++、Python、Go、C#
数据流支持 不支持 支持 支持
消息丢失 理论上不会丢失 理论上不会丢失 理论上不会丢失
文档完备性 极好 极好
商业公司实践 国内部分企业 LinkedIn 阿里巴巴
容错 无重试机制 无重试机制 支持重试,死信消息
顺序消息 支持 支持 支持
定时消息 不支持 不支持 支持
事务消息 不支持 支持 支持
消息轨迹 不支持 不支持 支持
消息查询 数据库中查询 不支持 支持
重放消息 不清楚 暂停重放 实时重放
宕机 自动切换 自动选主 手动重启