01消息队列系列-对消息队列的理解

01消息队列系列-对消息队列的理解

原文链接




https://mp.weixin.qq.com/s/M9bNEvGlkHL9bNRsW_TAqA


https://mp.weixin.qq.com/s/5JEWiFozCewZ5yHwGE7pRg

一、消息队列的由来

在没了解消息队列之前,已经听过很多概念了,例如JMS、AMQP、ActiveMQ、RabbitMQ、RocketMQ、Kafka等等。所以我们需要先从历史角度来理清这些MQ和协议之间的关系。


消息中间件其实诞生的很早,在互联网应用还是一片荒芜的年代,有个美国的印度小哥Vivek Ranadive 就设想了一种通用软件总线,采用发布订阅的模式,类似于电脑主板上的总线,新的设备或者程序如果想和电脑上其他的设备软件通信,只需要按照协议对接总线就可以完成接入和通信。
image.png
在 1983 年,26岁的印度小哥 Vivek Ranadive 创办了一家公司 Teknekron,实现了世界上第一个消息中间件The Information Bus(TIB)。很快 TIB 软件受到了企业的欢迎,最初被高盛集团用于解决金融交易,Teknekron 的业务发展速度甚至引起了当时最牛逼的 IT 公司 IBM 的注意。于是 IBM 也开始组建团队来研发自己的消息队列软件,这才有了后来的wesphere mq,不久微软也加入了战团。

由于商业壁垒,每个软件厂商都按照自己的标准来实现软件通信,导致企业客户不能随便更换 MQ 平台。为了打破这个壁垒,同时为了能够让消息在各个消息队列平台间互融互通, JMS (Java Message Service) 应运而生 。JMS 试图通过提供公共 Java API 的方式,隐藏单独 MQ 产品供应商提供的实现接口,从而跨越了壁垒,已解决互通问题。

从技术上讲, Java 应用程序只需针对 JMS API 进行编程,选择合适的 MQ 驱动即可, JMS 会打理好其他部分,就好比类似于 JDBC,对于开发者来说,只需要编写好 sql,具体是使用 oracle 还是 mysql 或者 sqlserver,由具体的厂商来提供驱动包文件即可,开发者无需关心具体的数据库厂商,从而大大的提升了开发效率、降低了开发难度。

ActiveMQ 就是 JMS 的 一种具体实现。

  • JMS - 点对点模型

image.png

  • JMS - 发布订阅模型

image.png
尽管使用标准化接口能有效的融合众多不同的 MQ 产品,但是也暴露出很多问题,例如有些 MQ 产品提供了非常高级的功能,但由于标准化接口的限制,导致用户无法使用,所以急需一种新的消息通信标准化方案。

在 2006 年 6 月,由 Cisco 、 Redhat 、iMatix 等人联合制定了 AMQP 的公开标准,由此 AMQP 登上了历史的舞台。

AMQP 是应用层协议的一个开放标准,以解决众多消息中间件的需求和拓扑结构问题,它为面向消息的中间件设计,基于此协议的客户端与消息中间件可传递消息,同时并不受产品、开发语言等条件的限制。

  • JMS vs AMQP

image.png
RabbitMQ 就是 AMQP 的一种具体实现。
image.png
随着时间的推进,虽然 AMQP 规范能适用的业务场景很多,但是 LinkedIn(领英) 在实现消息队列的时候觉得 AMQP 规范并不适合自己,于是在设计 Kafka 的时候,并不支持 AMQP 所有的特性。

同时阿里巴巴的 RocketMQ 在实现上也借鉴了 Kakfa 的思想,也不支持 AMQP 协议,并且你会发现在 Kafka 和 RocketMQ 中都有类似 Topic 和 Consumer Group 的概念,而这些概念在 AMQP 协议中并不存在。

二、为什么要使用消息队列

消息中间件虽然发展了很多年,但是不是每个项目都有机会能接触到消息队列,对于初次接触 MQ 的同学,难免会发出一些疑问!什么是消息队列为什么要使用消息队列使用消息队列有哪些弊端

对于传统的应用程序,如果需要向另一个应用程序发送信息,只需要向其发出请求即可!
image.png
这种方式虽然简单直接,但是如果应用程序2突然挂了,应用程序1可能会因为服务异常,而无法继续提供服务!设想一下,在应用程序1和应用程序2之间,插入一个消息服务,主要用于接受消息和发送消息,这样应用程序1和应用程序2之间的依赖关系就解耦了,同时也不会因为任何一方当服务不可用时,无法继续提供服务!
image.png
其中插入的消息服务被称为消息队列
由此可见,引入消息队列带来的优势很明显:

  • 程序解耦:应用程序1和应用程序2在进行交互时,不会因为一方服务中断而导致服务停止;
  • 异步处理:程序解耦之后,带来的最大的好处就是可以异步处理,应用程序1只管把消息发送到消息中间件,应用程序2只需要从消息中间件中接受消息然后进行处理即可;

同时,基于异步处理特性,在某些业务场景下,例如商品秒杀活动,引入消息队列之后,当客户端请求量很大的时候,可以有效的进行流量削峰
image.png
如果没有中间层做缓冲,当进行商品秒杀时,一下突然大量请求涌入,很可能造成系统直接瘫痪,甚至宕机!


在大型网站系统中,如何通过日志快速实时定位系统异常的代码,可以说至关重要!


LinkedIn 开发的消息队列 Kafka,可以说是日志采集方面的王者,在中、大型系统开发中,将消息队列 Kafka 用在日志处理中,可以有效的解决大量日志传输的问题。


当然,引入消息队列也会带来很明显的弊端:

  • 系统可用性降低:在引入消息队列之前,你不用考虑消息丢失或者消息队列服务挂掉等等的情况,但是引入消息队列之后你就需要去考虑这些问题!
  • 系统复杂性提高:加入消息队列之后,你需要保证消息没有被重复消费、处理消息没有被正确处理的情况等等问题!


引入消息队列虽然会带来一些问题,俗话说,兵来将挡、水来土掩,这句话同样适用于 IT 开发者,有坑填坑!

对于系统可用性降低方面,通常常用的解决方案就是搭建消息服务集群,具体技术实现上可以是主从架构或者分布式架构,即使一台消息队列服务机器挂了,也不会影响消息队列无法提供服务!

对于系统复杂性提高方面,常用的解决方案也很多,例如接受者接受到消息之后,可以先将消息写入数据库,即时没有被正确处理,还可以走人工处理,或者消息消费失败,将消息重新入队等待下一次消费等等。

三、常见的消息队列对比

目前比较主流的 MQ 产品,有 ActiveMQ,RabbitMQ,RocketMQ,Kafka,并且他们都是开源的,他们各自也有各自的特点。
image.png
总结内容如下

  1. ActiveMQ 的社区算是比较成熟,但是较目前来说,ActiveMQ 的性能比较差,而且版本迭代很慢,不推荐使用。
  2. RabbitMQ 在吞吐量方面虽然稍逊于 Kafka 和 RocketMQ ,但是由于它基于 erlang 开发,所以并发能力很强,性能极其好,延时很低,达到微秒级。但是也因为 RabbitMQ 基于 erlang 开发,所以国内很少有公司有实力做erlang源码级别的研究和定制。如果业务场景对并发量要求不是太高(十万级、百万级),那这四种消息队列中,首选 RabbitMQ。如果是大数据领域的实时计算、日志采集等场景,用 Kafka 是业内标准的,绝对没问题,社区活跃度很高,绝对不会黄,何况几乎是全世界这个领域的事实性规范。
  3. RocketMQ 阿里出品,Java 系开源项目,源代码我们可以直接阅读,然后可以定制自己公司的MQ,并且 RocketMQ 有阿里巴巴的实际业务场景的实战考验。RocketMQ 社区活跃度相对较为一般,不过也还可以,文档相对来说简单一些。还有就是阿里出台的技术,你得应对这个技术万一被抛弃,社区黄掉的风险,如果你们公司有技术实力我觉得用RocketMQ 挺好的。
  4. Kafka 的特点其实很明显,就是仅仅提供较少的核心功能,但是提供超高的吞吐量,ms 级的延迟,极高的可用性以及可靠性,而且分布式可以任意扩展。同时 Kafka 最好是支撑较少的 topic 数量即可,保证其超高吞吐量。Kafka 唯一的一点劣势是有可能消息重复消费,那么对数据准确性会造成极其轻微的影响,在大数据领域中以及日志采集中,这点轻微影响可以忽略。Kafka天然适合大数据实时计算以及日志收集。

到此对消息队列的初步认识结束。

posted @ 2020-10-07 19:57  在线打工者  阅读(214)  评论(0编辑  收藏  举报