面试说熟练掌握各种MQ?那你先看看这道题,面试官必问!
写在前面
我们知道,目前市面上的MQ包括Kafka、RabbitMQ、ZeroMQ、RocketMQ等等。
那么他们之间究竟有什么本质区别,分别适用于什么场景呢?
上述抛出的问题,同样在不少公司的Java工程师面试中出现,特别是当你简历上的技术栈包含了这些技术,面试官往往喜欢用这个问题,对你进行摸底考察。
本文我们就一起来探讨一下。
(1)有Broker的暴力路由
这个流派最典型的就是Kafka,Kafka实际上为了提升性能,简化了MQ功能模型,仅仅提供了一些最基础的MQ相关的功能,但是大幅度优化和提升了吞吐量。
首先,这个流派一定是有一个Broker角色的,也就是说,Kafka需要部署一套服务器集群,每台机器上都有一个Kafka Broker进程,这个进程就负责接收请求,存储数据,发送数据。
Kafka的生产消费模型做的相对是比较暴力简单的,就是简单的数据流模型。
简单来说,他有一个概念,叫做“Topic”,你可以往这个“Topic”里写数据,然后让别人从这里来消费。
这个Topic可以划分为多个Partition,每个Partition放一台机器上,存储一部分数据。
在写消息到Topic的时候,会自动把你这个消息给分发到某一个Partition上去。
然后消费消息的时候,有一个Consumer Group的概念,你部署在多台机器上的Consumer可以组成一个Group,一个Partition只能给一个Consumer消费,一个Cosumer可以消费多个Partition,这是最最核心的一点。
通过这个模型,保证一个Topic里的每条消息,只会交给Consumer Group里的一个Consumer来消费,形成了一个Queue(队列)的效果。
假如你想要有一个Queue的效果,也就是希望不停的往Queue里写数据,然后多个消费者消费,每条消息就只能给一个消费者,那么通过Kafka来实现,其实就是生产者写多个Partition,每个Partition只能给Consumer Group中的一个Consumer来消费。如下图所示:
如果要实现Publish/Subscribe的模型呢?就是说生产者发送的每条消息,都要让所有消费都消费到,怎么实现?
那就让每个消费者都是一个独立的消费组,这样每条消息都会发送给所有的消费组,每个消费组里那唯一的一个消费者一定会消费到所有的消息。
但是除此之外,Kafka就没有任何其他的消费功能了,就是如此简单,所以属于一种比较暴力直接的流派。
它就是简单的消费模型,实现最基础的Queue和Pub/Sub两种消费模型,但是内核中大幅度优化和提升了性能以及吞吐量。
所以Kafka天生适合的场景,就是大数据领域的实时数据计算的场景。
因为在大数据的场景下,通常是弱业务的场景,没有太多复杂的业务系统交互,而主要是大量的数据流入Kafka,然后进行实时计算。
所以就是需要简单的消费模型,但是必须在内核中对吞吐量和性能进行大幅度的优化。
因此Kafka技术通常是在大数据的实时数据计算领域中使用的,比如说每秒处理几十万条消息,甚至每秒处理上百万条消息。
(2)有Broker的复杂路由
第二个流派,就是RabbitMQ为代表的流派,他强调的不是说如何提升性能和吞吐量,关注的是说要提供非常强大、复杂而且完善的消息路由功能。
所以对于RabbitMQ而言,他就不是那么简单的Topic-Partition的消费模型了。
在RabbitMQ中引入了一个非常核心的概念,叫做Exchange,这个Exchange就是负责根据复杂的业务规则把消息路由到内部的不同的Queue里去。
举个例子,如果要实现最简单的队列功能,就是让exchange往一个queue里写数据,然后多个消费者来消费这个queue里的数据,每条消息只能给一个消费者,那么可以是类似下面的方式。
如果想要实现Pub/Sub的模型,就是一条消息要被所有的消费者给消费到,那么就可以让每个消费者都有一个自己的Queue,然后绑定到一个Exchange上去。
接着,这个Exchange就设定把消息路由给所有的Queue即可,如下面这样。
此时Exchange可以把每条消息都路由给所有的Queue,每个Consumer都可以从自己的Queue里拿到所有的消息。
RabbitMQ这种流派,其实最核心的是,基于Exchange这个概念,他可以做很多复杂的事情。
比如:如果你想要某个Consumer只能消费到某一类数据,那么Exchange可以把消息里比如带“XXX”前缀的消息路由给某个Queue。或者你可以限定某个Consumer就只能消费某一部分数据。总之在这里你可以做很多的限制,设置复杂的路由规则。
但是也正是因为引入了这种复杂的消费模型,支持复杂的路由功能,导致RabbitMQ在内核以及架构设计上没法像Kafka做的那么的轻量级、高性能、可扩展、高吞吐,所以RabbitMQ在吞吐量上要比Kafka低一个数量级。
所以这种流派的MQ,往往适合用在Java业务系统中,不同的业务系统需要进行复杂的消息路由。
比如说业务系统A发送了10条消息,其中3条消息是给业务系统B的,7条消息是给业务系统C的,要实现这种复杂的路由模型,就必须依靠RabbitMQ来实现。
当然,对于这种业务系统之间的消息流转而言,可能不需要那么高的吞吐量,可能每秒业务系统之间也就转发几十条或者几百条消息,那么就完全适合采用RabbitMQ来实现。
(3)无Broker的通信流派
ZeroMQ代表的是第三种MQ。说白了,他是不需要在服务器上部署的,就是一个客户端的库而已。
也就是说,他主要是封装了底层的Socket网络通讯,然后一个系统要发送一条消息给另外一个消息消费 。
通过ZeroMQ,本质就是底层ZeroMQ发送一条消息到另外一个系统上去。
所以ZeroMQ是去中心化的,不需要跟Kafka、RabbitMQ一样在服务器上部署的。
他主要是用来进行业务系统之间的网络通信的,有点类似于比如你是一个分布式系统架构,那么此时分布式架构中的各个子系统互相之间要通信,你是基于Dubbo RPC?还是Spring Cloud HTTP?
可能上述两种你都不想要,就是要基于原始的Socket进行网络通信,简单的收发消息而已。
此时就可以使用ZeroMQ作为分布式系统之间的消息通信,如下面那样。
(4)总结
其实现在基本上MQ主要就是这三个流派,很多小众的MQ一般很少有人会用。
而且用MQ的场景主要就是两大类:
- 业务系统之间异步通信
- 大数据领域的实时数据计算
所以一般业务系统之间通信就是会采用RabbitMQ/RocketMQ,需要复杂的消息路由功能的支撑。
大数据的实时计算场景会采用Kafka,需要简单的消费模型,但是超高的吞吐量。
至于ZeroMQ,一般来说,少数分布式系统中子系统之间的分布式通信时会采用,作为轻量级的异步化的通信组件。
面试说熟练掌握各种MQ?那你先看看这道题,面试官必问!的更多相关文章
- 那些面试官必问的JAVA多线程和并发面试题及回答
Java多线程面试问题 1. 进程和线程之间有什么不同? 一个进程是一个独立(self contained)的运行环境,它可以被看作一个程序或者一个应用.而线程是在进程中执行的一个任务.Java运行环 ...
- 阿里面试官必问的12个MySQL数据库基础知识,哪些你还不知道?
数据库基础知识 1.为什么要使用数据库 (1)数据保存在内存 优点: 存取速度快 缺点: 数据不能永久保存 (2)数据保存在文件 优点: 数据永久保存 缺点: 1)速度比内存操作慢,频繁的IO操作. ...
- 面试官再问我如何保证 RocketMQ 不丢失消息,这回我笑了!
最近看了 @JavaGuide 发布的一篇『面试官问我如何保证Kafka不丢失消息?我哭了!』,这篇文章承接这个主题,来聊聊如何保证 RocketMQ 不丢失消息. 0x00. 消息的发送流程 一条消 ...
- js原生方法传参的细节(面试必问)
废话不说,直接上题. slice(),接收两个参数,第一个为开始index(从0开始),第二个为结束的index(也是从0开始,但是不包括index本身,只到index-1).返回值是截取的数组,原数 ...
- JVM工作原理和特点(一些二逼的逼神面试官会问的问题)
作为一种阅读的方式了解下jvm的工作原理 ps:(一些二逼的逼神面试官会问的问题) JVM工作原理和特点主要是指操作系统装入JVM是通过jdk中Java.exe来完毕,通过以下4步来完毕JVM环境. ...
- linux驱动工程面试必问知识点
linux内核原理面试必问(由易到难) 简单型 1:linux中内核空间及用户空间的区别?用户空间与内核通信方式有哪些? 2:linux中内存划分及如何使用?虚拟地址及物理地址的概念及彼此之间的转化, ...
- 面试必问的SpringCloud实现原理图
引言 面试中面试官喜欢问组件的实现原理,尤其是常用技术,我们平时使用了SpringCloud还需要了解它的实现原理,这样不仅起到举一反三的作用,还能帮助轻松应对各种问题及有针对的进行扩展. 以下是 课 ...
- 互联网公司面试必问的Redis题目
Redis是一个非常火的非关系型数据库,火到什么程度呢?只要是一个互联网公司都会使用到.Redis相关的问题可以说是面试必问的,下面我从个人当面试官的经验,总结几个必须要掌握的知识点. 介绍:Redi ...
- 【面试必问】python实例方法、类方法@classmethod、静态方法@staticmethod和属性方法@property区别
[面试必问]python实例方法.类方法@classmethod.静态方法@staticmethod和属性方法@property区别 1.#类方法@classmethod,只能访问类变量,不能访问实例 ...
随机推荐
- 搭建私有docker仓库
安装docker yum install docker 启动docker systemctl start docker 拉取registry镜像 docker pull registry 创建仓库配置 ...
- cmd杀死进程
打开cmd 1.查看所有进程占用的端口 输入:netstat –ano(查看所有进程,查找相应占用端口的程序的pid) 直接查看占用指定端口的程序的pid 输入:netstat -ano|findst ...
- Linux查看用户列表
cat /etc/passwd 可以查看所有用户的列表w 可以查看当前活跃的用户列表cat /etc/group 查看用户组 groups 查看当前登录用户的组内成员groups gliethttp ...
- Django-F和Q函数作用与使用
F函数 能够解析对现有查询对象的引用的对象. obj = Score.objects.get(stuid=') obj.score += 1 obj.order.save() 执行出的SQL语句 wh ...
- 根据判断数组不为空然后取他的值----数组不会为空---只能判断其size是否大于0
private List<Integer> classId=new ArrayList<Integer>(); business.getClassId()!=null 以上为错 ...
- session 与 cookie 区别-----https://segmentfault.com/a/1190000013447750?utm_source=tag-newest
cookie数据存放在客户的浏览器上,session数据放在服务器上. cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗考虑到安全应当使用session. sessi ...
- swift kilo版代码更新
今天重新搭建swift服务器,git下代码后一时好奇,进入kilo/stable branch后,与四个月前下载的swift/kilo版本做了个比较.使用diff命令完成.发现代码还是略有区别. di ...
- jsp之${CTX}理解
jsp之${CTX} 根据自己的需要选择以下标签. <%@ taglib uri="/struts-tags" prefix="s"%> <% ...
- [bzoj1293][SCOI2009]生日礼物(单调队列)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1293 分析: 问题的关键就是选择每种颜色的哪一个好.可以先把每种颜色的第一个一起,更新 ...
- Spark之安装和使用
Scala安装 Spark使用Scala开发,安装的Scala版本必须和Spark使用的版本一致,否则使用Scala编写的Spark任务会有兼容性问题 可以到Spark官网查看确定Scala版本,或者 ...