前言

学完了Redis,那你一定不能错过消息队列,要说他俩之间的关联?关联是有的,但也不见得很大,只是他们都是大数据领域常用的一种工具,一种用来提高程序运行效率的工具。常见于高并发,大数据,都是微服务领域不可获取的工具。要说微服务的工具,还有很多,包括我们前面学过dubbo,es,nacos,seata,sentinel等,值得一提的是,大部分的工具其实都不需要我们写太多的代码,这也是工具本身的特点,它会在内部帮我们处理好要走的流程,提高开发效率。消息队列也是一样的,下面,我们就来了解一下消息队列吧。

消息队列

什么是消息队列

消息队列中间件是分布式系统中的重要组件,主要用于解决应用解耦,异步消息,流量削锋等问题,实现高性能,高可用,可伸缩的最终目的。说人话就是:消息队列是通过异步的方式来传递数据的过程。比如我们又想听歌,又要吃饭,异步方式下,边听歌边吃饭,互不影响,就是这么简单。

为什么使用消息队列

我们前面学习微服务时有一个创建订单的操作,使用Dubbo处理的调用,分别是减库存,删购物车数据,生成订单,分成了这三步,我们来思考下,这三步有什么必然联系吗?我可不可以打乱顺序来做?我在微服务中使用了Seata,就是为了解决分布式事务同步问题,即使某一步出了问题,我也可以自动回滚,那么这三步之前其实就没有任何联系了。

但是Dubbo中,这三步是按照代码顺序来执行的,而且是等待返回后才执行下一步的,如果同一时间有很多创建订单的请求过来,在不使用消息队列异步的情况下,服务器的压力就要翻好几倍了,这不符合我们对程序高可用性的设计,所以这里最好的办法就是让他们并发的,异步的执行。

诚然,有些调用是需要等待的,比如要先查一个id,再通过id获取详情的。但并不是所有的请求都需要如此,所以在使用中需要根据实际情况来做。

消息队列的特点

这在上面我们已经提到了,网上普遍流传的特征主要是三个:解耦,异步,削峰。但根据实际使用,它还有另外两个功能:日志和通讯。这两个功能也是不可忽视的,像日志,虽然在业务上不体现出其重要性,一旦出现问题,其重要性自然不言而喻。下面,我们来看看他们分别都是做什么的。

解耦

解耦是针对业务的,是业务就有生产者和消费者,而生产者和消费者也绝对不可能只有一对,所以是一对多的关系,还有一些模块或者对象,既是生产者,也是消费者。

生产者和消费者之间的关系是:生产者负责将消息正确的写入消息队列,其他的不关心。消费者负责从消息队列中读取消息,在进行逻辑处理。你会发现,生产者和消费者之间没有任何的直接交互。

没有交互,就没有耦合。而耦合度越低的代码,越有利于维护和扩展。说起来,很像是移动端里的通知或者广播。

异步

说到异步,不得不说说同步:同步是请求的调用方直到调用结果返回之前一直处于等待状态,这期间,调用方之后的业务将不会执行,一直等待调用结束后再执行。

异步,我相信不需要我说太多,大家都知道它的工作方式:无需等待,直接执行。

异步处理的主要目的是:减少请求响应时间,实现非核心流程异步化,提高系统响应性能。所以说,同步还是异步,都是需要的,只是看业务能接受等待的程度有多少,根据需要选择即可。

但是异步有一个明显的缺点,我写进异步队列的任务是存在延时的。调用方无法得知何时能得到响应,所以使用异步时,也要考虑业务是否能接受这样的延时,举个例子:发送验证码。这就是个典型的消息队列,同一时间谁也不知道有多少条短信需要发送,都是放在队列里执行的,如果执行的任务很多,那么你收到验证码的时间就会很长。

削峰

削峰的完整表达应该是削峰填谷。在并发峰值超过当前系统处理能力时,将没处理的信息保存在消息队列中,在后面较闲的时间中去处理,直到所有数据依次处理完成。这能够防止在并发峰值时短时间大量请求而导致的系统不稳定。上面提到的短信验证码也是这样的,所以延时是无法避免的。

消息日志

我们当然希望日志可以实时保存,这样出了问题才能很好的定位。甚至我们在讲Redis的时候提到过AOF,忘记的童鞋回头再看看:Java开发 – Redis初体验

AOF保存的就是日志,1s一次,Redis的保存机制是什么,博主不清楚,但我非常清楚的是,这种实时的日志保存必然会造成服务器的巨大消耗,前提是数据量非常大的情况。此时如果将日志放在消息队列中,忙的时候等待,在不忙的时候处理,也不失为一种好的效率机制。在这里,我们要区分日志登等级,如果是Redis这种可断电恢复的日志级别,我们可能不太希望它出现延时,是吧?

通讯

消息队列一般都内置了高效的通信机制,因此可以用于单纯的消息通讯,比如实现点对点消息队列或者聊天室。关于此,涉及到的知识很广,刨根问题的话还是自己查吧,说实话,博主也不可能讲太清楚。

常见消息队列

目前博主所知的消息队列有以下几种:ActiveMQ,RabbitMQ,ZeroMQ,Kafka,MetaMQ,RocketMQ。排名不分先后!!!

ActiveMQ

ActiveMQ是前几年流行的,一些老项目可能用到。Apache ActiveMQ是Apache软件基金会所研发的开放源代码消息中间件;由于ActiveMQ是一个纯Java程序,因此只需要操作系统支持Java虚拟机,ActiveMQ便可执行。但目前主流的消息队列更好用,这个便慢慢被搁浅了,目前用的人应该会慢慢减少,毕竟没有几个人挡得住Kafka和RabbitMQ的摧残。

RabbitMQ

RabbitMQ是使用Erlang语言开发的开源消息队列系统,基于AMQP协议来实现。AMQP的主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、安全。AMQP协议更多用在企业系统内,对数据一致性、稳定性和可靠性要求很高的场景,对性能和吞吐量的要求还在其次。所以在Java业务中使用很多,目前我所知道的很多都是用的此消息队列,只不过大家评价都是:功能强,性能一般。与其相反的,就是Kafka了:性能强,功能弱。

这是因为他们设计的目的不一样,RabbitMQ 在有大量消息堆积的情况下性能会下降,其优势体现在功能上。而Kafka一开始是用来处理海量日志的,所以体现出来就是性能强,功能弱。

所谓,尺有所短,寸有所长,正是这个道理。全都兼顾的几乎是不存在的。

ZeroMQ

ZMQ(以下ZeroMQ简称ZMQ)是一个简单好用的传输层,像框架一样的一个socket library,他使得Socket编程更加简单、简洁和性能更高。是一个消息处理队列库,可在多个线程、内核和主机盒之间弹性伸缩。ZMQ的明确目标是“成为标准网络协议栈的一部分,之后进入Linux内核”。还未看到它们的成功。但是,它无疑是极具前景的、并且是人们更加需要的“传统”BSD套接字之上的一层封装。ZMQ让编写高性能网络应用程序极为简单和有趣。

以上是官方的自high,具体怎么样,还需要大家的评判。不过由于其提供跨越多种传输协议的套接字,基于此,还是有一部分人在用的。

Kafka

Kafka是由Apache软件基金会开发的一个开源流处理平台,由Scala和Java编写。Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者在网站中的所有动作流数据。 这种动作(网页浏览,搜索和其他用户的行动)是在现代网络上的许多社会功能的一个关键因素。 这些数据通常是由于吞吐量的要求而通过处理日志和日志聚合来解决。 对于像Hadoop一样的日志数据和离线分析系统,但又要求实时处理的限制,这是一个可行的解决方案。Kafka的目的是通过Hadoop的并行加载机制来统一线上和离线的消息处理,也是为了通过集群来提供实时的消息。

值得一提的是,kafka的诞生,是为了解决linkedin的数据管道问题,起初linkedin采用了ActiveMQ来进行数据交换,不过,这也已经是十几年前的事了。

哦,另外要说的是,Kafka自身服务和消费者都需要依赖Zookeeper,而Zookeeper的作用是:可以修改服务器系统中的所有软件配置。所以,长此以往,很多软件就删除了自己写配置文件的功能,而直接从Zookeeper中获取。

MetaMQ

MetaMQ是一个基于以太坊的可扩展分布式消息队列,由于其介绍非常少,所以使用的人也不多,此消息队列就不再说明了,有兴趣的可自行了解。

RocketMQ

RocketMQ是阿里开源的消息中间件,它是纯Java开发,具有高吞吐量、高可用性、适合大规模分布式系统应用的特点。其起源于Kafka,但Kafka无法满足其需求,尤其表现在低延迟和高可靠性方面,在这种情况下,RocketMQ诞生了,它是通过一个新的消息传递引擎来处理更广泛的消息用例,覆盖从传统的pub/sub场景到高容量的实时零误差的交易系统。

Apache RocketMQ 自诞生以来,因其架构简单、业务功能丰富、具备极强可扩展性等特点被众多企业开发者以及云厂商广泛采用。历经十余年的大规模场景打磨,RocketMQ 已经成为业内共识的金融级可靠业务消息首选方案,被广泛应用于互联网、大数据、移动互联网、物联网等领域的业务场景。

不过据说其没有Web管理界面,提供了一个CLI(命令行界面) 管理工具来查询管理诊断各种问题。但是在新版本中,博主注意到,已经有管理页面了。具体,推荐查看此博客:Rocketmq单机部署以及管理界面 – 知乎

感兴趣的可以看看其官网:为什么选择RocketMQ | RocketMQ

总结

总结,也没什么好总结的,各有千秋吧,不过目前使用最多的还是RabbitMQ和Kafka,关于消息队列,想了解的更详细的话,推荐这篇博客,讲的很深:常见消息队列 RabbitMQ、RocketMQ、ActiveMQ、Kafka、ZeroMQ、MetaMQ 等详解和对比 – 知乎

结语

最后了,说点啥?还是说说关于消息队列博主的教程方向吧。后续,博主会通过两篇博客来分别讲解RabbitMQ和Kafka的实战用法,此篇权当给大家一个前瞻,了解下即可。里面内容都是博主的一些体会和参考一些词条写成的,如有不准确的地方,欢迎指正,码文不易,觉得不错,请不要吝惜你们的赞,收藏和评论,谢谢。