RabbitMQ设计原理解析

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
云解析DNS,个人版 1个月
简介: RabbitMQ设计原理解析

背景


RabbitMQ现在用的也比较多,但是没有过去那么多啦。现在很多的流行或者常用技术或者思路都是从过去的思路中演变而来的。了解一些过去的技术,对有些人来说可能会产生众里寻他千百度的顿悟,加深对技术的理解,更好的应用于工作中去。


本篇整体采用从浅到深的逻辑结构来描述。

 

入门部分


什么是MQ


MQ全称是Message Queue,消息的队列。因为是队列,所以遵循FIFO先进先出原则。


因为存放的是消息,所以是一种跨进程的通信机制。


为什么使用MQ


流量削峰


这个跟很火的小吃店门口的排队原理是一样的。实时调用就好像是大家蜂拥而至,如果系统处理能力不够,就会让店家手忙脚乱,说不定会在冰激凌上浇上可乐。排队能保证有条不紊,代价是整体处理速度会慢些。


异步处理


当A调用B,B可能要花很长一段时间来完成。这时候一般有三种方式来异步处理。A调用B,B返回A说收到调用请求了。同步请求已经完成,但B的执行才刚开始。这时候,第一种方式是A每隔一段时间来查询一次,看B是否执行完,这是拉的方式;第二种方式是A提供一个回调地址,B执行完之后回调A,这是推的方式;第三种就是使用MQ,A使用MQ给B发消息,B处理完再回一个消息,好处是上面提到的同时可以流量削峰。


应用解耦


MQ实现了逻辑解耦+物理解耦。逻辑上,将请求和结果处理分开了;物理上,系统只用与MQ通信。听起来,MQ要优雅很多,但是上面提到异步处理的三种方式的前两种,现在也多很常见。那是因为MQ是有代价的,那就是需要一套MQ设施。做开放平台,用户之间的唯一设施就是互联网,这时候更依赖双方的协议约定,所以前两种异步处理方式不会被MQ取代。


MQ的分类


ActiveMQ是早期的MQ,倚老卖老一下,我那个年代用过,目前优势已经不太明显了。

Kafka号称是大数据的杀手锏,以百万级TPS吞吐量名声大噪。时效是ms级别,分布式的可用性高。消费者采用拉的方式获取消息,消息有序,通过控制可以保证消息仅被消费一次。但是单机超过64个分区,load会明显飙高;实时性取决于轮询时间间隔,关键是有可能丢消息,不适合订单业务中使用。


RocketMQ是国货,用Java语言实现,在设计时参考了Kafka,单机吞吐量达到十万级别,分布式架构可用性高,消息可以0丢失,扩展性高。但是支持的客户端成熟的也就是Java,核心代码没有实现JMS,迁移需要修改大量代码。


RabbitMQ是erlang开发的,吞吐量达到万级别,稳定、健壮、跨平台,支持多种语言,企业间通信中常用。


JMS支持


RabbitMQ不支持JMS协议。这个很好理解。因为JMS是Java消息服务,提供了消息传递的Java标准API。而RabbitMQ是Erlang写的,对Java的支持会弱一些。但是RabiitMQ实现了AMQP标准协议。AMQP只是统一了数据交换的标准格式,与语言无关。

 

核心部分


核心概念


所有的MQ都由生产者、消费者和broker(队列)三部分组成。但是不同的实现,根据核心思想不同,内部结构也各有特色。


比如银行系统中常用的跨银行间通信的MQ,相当于两组MQ拼起来的。


普通MQ


1112728-20211027143038977-1424004659.png


跨企业MQ


1112728-20211027143059576-272496389.png


这样做的好处是任何一端网络出现问题,都可以暂存消息,等待网络恢复,不丢失消息。消息的重试放在broker端,减少了应用端的复杂度。为什么这里举例时提到银行间使用呢,因为使用这种模式的MQ,最重要的是有钱。因为想达到理想效果,要拉专线,并使用高配机器。


RabbitMQ和Kafka是一样的


再回来考虑普通MQ的场景,如果这个MQ是RabbitMQ。组件细化一下是这样:


1112728-20211027143116715-1126447546.png


这张图上来看,其实RabbitMQ和Kafka是一样的。来看Kafka的:


1112728-20211027143129769-1616445448.png


表面上来看,RabbitMQ的服务器(Broker)端由Exchange和Queue两部分组成。


Exchange是交换机,交换机是做路由的。Kafka生产者发到Broker也需要路由啊,来决定路由到哪个Partition(也就是队列)中去。只不过Kafka的路由模式很固定,就是先找到哪个topic,然后使用负载均衡的策略找到一个Partition来投递消息。Kafka是用了逻辑概念topic简化了exchange路由,所以Kafka的路由功能也很单一。


表面上,RabbitMQ的生产者和消费者与服务端都是Channel信道来相连。Channel是复用连接来进行通信的,Kafka也是需要的,只是它内部帮我们把这些与核心功能关系不大的都自己内置实现了。而RabbitMQ暴露给用户,提供了更高的灵活性。


上面的两段如果我没有讲明白,也没有关系。只要知道更年轻的Kafka没有Exchange和Channel的概念是类似于采取了约定大于配置的方式提供的服务。


核心功能


RabbitMQ的核心实际上就是AMQP的核心:MessageQueue、Exchange和Binding。


MessageQueue就是消息队列,一个队列里的一条消息,也就是同一个message ID对应的消息,不管有多少个消费者来分摊压力,也只能被消费一次。消息队列和消费者之间有ack机制,消息一旦确认安全送达,RabbitMQ服务端就可以安全删除消息了。


Binding是MessageQueue与Exchange之间的连接,Exchange只能给Binding的MessageQueue发送消息。


Exchange有四种类型:fanout、topic、direct和header。本质上就是有一堆MessageQueue,一个消息是要被复制几份,发到哪几个Binding的消息队列去。


Exchange给定了规则:fanout是对每个消息队列复制一份发送;direct意思是只发指定的一份,不复制;topic是发送通配符匹配的几份;header可以指定一些其他的过滤条件发送。消息从生产者发送到exchange之后也有ack机制来保证消息的可靠传输。


Kafka只有topic的概念。这是因为Kafka的设计上消息只用存一份,通过游标,发送后不立即删除消息。多个消费者组可以互不影响的消费。这是Kafka的一大改进。


内部原理


大家面试时有没有被问过:Kafka怎么保证消息能且仅能收到一次?这是个埋坑题,是与面试官斗智斗勇的开始。什么幂等、事务、流式EOS呀,其实呢,Kafka本身是不保证仅且仅收到一次的,所以这些实现方法都不优雅。


RabbitMQ通过AMQP事务机制,还有上面已经提过的ack也就是confirm两种可选方式保证消息被收到。


但是最为优雅的实现是IBM的Websphere MQ。因为这是收费的,所以研究的人不多。它通过消息序列号保证消息不丢失、不重传。


通道为每条消息的传送分配一个序列号,它会自动累积增值。消息序列号由发送通道分配,是通道的一个永久属性,每当发送一条消息,消息序列号就加一。通道的相关属性SEQWRAP标识序号的最大值,缺省为999,999,999。序列号越界后自动归零,从头开始。


正常情况下,通道两端的消息序列号或者相等或相差为一。双方对前面的某一条或一批消息是否发送成功理解不一致。在解决了不确定的消息后,可以用MQSC命令通过重置消息序号将双方调整到一致。一旦连接断开后,通道重连时双方会将消息序号同步。

相关实践学习
消息队列RocketMQ版:基础消息收发功能体验
本实验场景介绍消息队列RocketMQ版的基础消息收发功能,涵盖实例创建、Topic、Group资源创建以及消息收发体验等基础功能模块。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
相关文章
|
4天前
|
消息中间件 存储 数据库
深入学习RocketMQ的底层存储设计原理
文章深入探讨了RocketMQ的底层存储设计原理,分析了其如何通过将数据和索引映射到内存、异步刷新磁盘以及消息内容的混合存储来实现高性能的读写操作,从而保证了RocketMQ作为一款低延迟消息队列的读写性能。
|
4天前
|
消息中间件 负载均衡 API
RocketMQ生产者负载均衡(轮询机制)核心原理
文章深入分析了RocketMQ生产者的负载均衡机制,特别是轮询机制的实现原理,揭示了如何通过`ThreadLocal`技术和消息队列的选播策略来确保消息在多个队列之间均衡发送,以及如何通过灵活的API支持自定义负载均衡策略。
|
4天前
|
域名解析 缓存 网络协议
DNS解析过程原理!
DNS解析过程原理!
|
4天前
|
消息中间件 存储 负载均衡
RocketMQ消费者消费消息核心原理(含长轮询机制)
这篇文章深入探讨了Apache RocketMQ消息队列中消费者消费消息的核心原理,特别是长轮询机制。文章从消费者和Broker的交互流程出发,详细分析了Push和Pull两种消费模式的内部实现,以及它们是如何通过长轮询机制来优化消息消费的效率。文章还对RocketMQ的消费者启动流程、消息拉取请求的发起、Broker端处理消息拉取请求的流程进行了深入的源码分析,并总结了RocketMQ在设计上的优点,如单一职责化和线程池的使用等。
RocketMQ消费者消费消息核心原理(含长轮询机制)
|
4天前
|
消息中间件 存储 RocketMQ
2分钟看懂RocketMQ延迟消息核心原理
本文从源码层面解析了RocketMQ延迟消息的实现原理,包括延迟消息的使用、Broker端处理机制以及定时任务对延迟消息的处理流程。
2分钟看懂RocketMQ延迟消息核心原理
|
4天前
|
消息中间件 存储 缓存
RocketMQ发送消息原理(含事务消息)
本文深入探讨了RocketMQ发送消息的原理,包括生产者端的发送流程、Broker端接收和处理消息的流程,以及事务消息的特殊处理机制,提供了对RocketMQ消息发送机制全面的理解。
RocketMQ发送消息原理(含事务消息)
|
12天前
|
域名解析 负载均衡 网络协议
【域名解析DNS专栏】DNS解析中的Anycast技术:原理与优势
在互联网中,DNS将域名转换为IP地址至关重要。Anycast技术通过将同一IP地址分配给多台地理上分散的服务器,确保客户端总能连接到最近且最轻载的服务器,从而加速DNS解析、实现负载均衡、提升抵御DDoS攻击的能力及服务高可用性。通过动态路由协议如BGP实现,Anycast极大地增强了DNS系统的性能和稳定性。
34 2
|
14天前
|
机器学习/深度学习 运维 算法
深入探索机器学习中的支持向量机(SVM)算法:原理、应用与Python代码示例全面解析
【8月更文挑战第6天】在机器学习领域,支持向量机(SVM)犹如璀璨明珠。它是一种强大的监督学习算法,在分类、回归及异常检测中表现出色。SVM通过在高维空间寻找最大间隔超平面来分隔不同类别的数据,提升模型泛化能力。为处理非线性问题,引入了核函数将数据映射到高维空间。SVM在文本分类、图像识别等多个领域有广泛应用,展现出高度灵活性和适应性。
67 2
|
1天前
|
域名解析 存储 缓存
域名服务器 (DNS):工作原理及其优势
【8月更文挑战第19天】
17 0
|
5天前
|
安全 Nacos 数据安全/隐私保护
【技术干货】破解Nacos安全隐患:连接用户名与密码明文传输!掌握HTTPS、JWT与OAuth2.0加密秘籍,打造坚不可摧的微服务注册与配置中心!从原理到实践,全方位解析如何构建安全防护体系,让您从此告别数据泄露风险!
【8月更文挑战第15天】Nacos是一款广受好评的微服务注册与配置中心,但其连接用户名和密码的明文传输成为安全隐患。本文探讨加密策略提升安全性。首先介绍明文传输风险,随后对比三种加密方案:HTTPS简化数据保护;JWT令牌减少凭证传输,适配分布式环境;OAuth2.0增强安全,支持多授权模式。每种方案各有千秋,开发者需根据具体需求选择最佳实践,确保服务安全稳定运行。
21 0

推荐镜像

更多