RabbitMQ的应用场景

news/2024/12/29 10:58:14/

1.异步处理
消息队列的主要特点是异步处理,主要目的是减少请求响应时间,实现非核心流程异步化,提高系统响应性能。

所以典型的使用场景就是将比较耗时而且不需要即时(同步)返回结果的操作,作为消息放入消息队列。

2.应用解耦
使用了消息队列后,只要保证消息格式不变,消息的发送方和接收方并不需要彼此联系,也不需要受对方的影响,即解耦。

解耦是消息队列要解决的最本质问题。所谓解耦,简单点讲就是一个事务,只关心核心的流程。而需要依赖其他系统但不那么重要的事情,有通知即可,无需等待结果。换句话说,基于消息的模型,关心的是“通知”,而非“处理”。

每个成员不必受其他成员影响,可以更独立自主,只通过消息队列MQ来联系。

举一个例子:用户下订单流程,下订单后会发生扣库存这个动作,上游系统订单和下游系统扣库存,就可以通过上图的消息队列MQ来联系,扣库存异步化,从而实现订单系统与库存系统的应用解耦。

3.流量削锋
流量削锋也是消息队列中的常用场景,一般在秒杀或团抢活动中使用广泛。

应用场景:秒杀活动,一般会因为流量过大,导致流量暴增,应用挂掉。为解决这个问题,一般需要在应用前端加入消息队列。

试想上下游对于事情的处理能力是不同的。

比如,Web前端每秒承受上千万的请求,并不是什么神奇的事情,只需要加多一点机器,再搭建一些LVS负载均衡设备和Nginx等即可。

但数据库的处理能力却十分有限,即使使用SSD加分库分表,单机的处理能力仍然在万级。由于成本的考虑,我们不能奢求数据库的机器数量追上前端。

这种问题同样存在于系统和系统之间,如短信系统可能由于短板效应,速度卡在网关上(每秒几百次请求),跟前端的并发量不是一个数量级。

但用户晚上个半分钟左右收到短信,一般是不会有太大问题的。如果没有消息队列,两个系统之间通过协商、滑动窗口等复杂的方案也不是说不能实现。

但系统复杂性指数级增长,势必在上游或者下游做存储,并且要处理定时、拥塞等一系列问题。而且每当有处理能力有差距的时候,都需要单独开发一套逻辑来维护这套逻辑。所以,利用中间系统转储两个系统的通信内容,并在下游系统有能力处理这些消息的时候,再处理这些消息,是一套相对较通用的方式。

具体可以参考:阿里P8架构师谈:双11秒杀系统如何设计?
https://youzhixueyuan.com/how-to-design-double-11-seconds-kill-system.html

4日志处理
日志处理是指将消息队列用在日志处理中,比如Kafka的应用,解决大量日志传输的问题。

5消息通讯
消息队列一般都内置了高效的通信机制,因此也可以用于单纯的消息通讯,比如实现点对点消息队列或者聊天室等。

6最终一致性
最终一致性指的是两个系统的状态保持一致,要么都成功,要么都失败。

当然有个时间限制,理论上越快越好,但实际上在各种异常的情况下,可能会有一定延迟达到最终一致状态,但最后两个系统的状态是一样的。

业界有一些为“最终一致性”而生的消息队列,如:

 Notify(阿里)
 QMQ(去哪儿)等
其设计初衷,就是为了交易系统中的高可靠通知。

以一个银行的转账过程来理解最终一致性,转账的需求很简单,如果A系统扣钱成功,则B系统加钱一定成功。反之则一起回滚,像什么都没发生一样。

然而,这个过程中存在很多可能的意外:

 A扣钱成功,调用B加钱接口失败。
 A扣钱成功,调用B加钱接口虽然成功,但获取最终结果时网络异常引起超时。
 A扣钱成功,B加钱失败,A想回滚扣的钱,但A机器down机。
可见,想把这件看似简单的事真正做成,真的不那么容易。

所有跨VM的一致性问题,从技术的角度讲通用的解决方案是:

 强一致性,分布式事务,但落地太难且成本太高,后文会具体提到。
 最终一致性,主要是用“记录”和“补偿”的方式。在做所有的不确定的事情之前,先把事情记录下来,然后去做不确定的事情,结果可能是:成功、失败或是不确定,“不确定”(例如超时等)可以等价为失败。成功就可以把记录的东西清理掉了,对于失败和不确定,可以依靠定时任务等方式把所有失败的事情重新搞一遍,直到成功为止。
 回到刚才的例子,系统在A扣钱成功的情况下,把要给B“通知”这件事记录在库里(为了保证最高的可靠性可以把通知B系统加钱和扣钱成功这两件事维护在一个本地事务里),通知成功则删除这条记录,通知失败或不确定则依靠定时任务补偿性地通知我们,直到我们把状态更新成正确的为止。
 整个这个模型依然可以基于RPC来做,但可以抽象成一个统一的模型,基于消息队列来做一个“企业总线”。
 具体来说,本地事务维护业务变化和通知消息,一起落地(失败则一起回滚),然后RPC到达broker,在broker成功落地后,RPC返回成功,本地消息可以删除。否则本地消息一直靠定时任务轮询不断重发,这样就保证了消息可靠落地broker。
 broker往consumer发送消息的过程类似,一直发送消息,直到consumer发送消费成功确认。
 我们先不理会重复消息的问题,通过两次消息落地加补偿,下游是一定可以收到消息的。然后依赖状态机版本号等方式做判重,更新自己的业务,就实现了最终一致性。
最终一致性不是消息队列的必备特性,但确实可以依靠消息队列来做最终一致性的事情。

另外,所有不保证100%不丢消息的消息队列,理论上无法实现最终一致性。好吧,应该说理论上的100%,排除系统严重故障和bug。

像Kafka一类的设计,在设计层面上就有丢消息的可能(比如定时刷盘,如果掉电就会丢消息)。哪怕只丢千分之一的消息,业务也必须用其他的手段来保证结果正确。

7广播
消息队列的基本功能之一是进行广播。

如果没有消息队列,每当一个新的业务方接入,我们都要联调一次新接口。有了消息队列,我们只需要关心消息是否送达了队列,至于谁希望订阅,是下游的事情,无疑极大地减少了开发和联调的工作量。

比如本文开始提到的产品中心发布产品变更的消息,以及景点库很多去重更新的消息,可能“关心”方有很多个,但产品中心和景点库只需要发布变更消息即可,谁关心谁接入。


http://www.ppmy.cn/news/945519.html

相关文章

Unity 景深Depth Of Field

目录 介绍 准备 设置 基于Unity Builtin 管线 基于Unity URP 基于Unity HDRP 介绍: 景深效果Depth Of Field是摄影界的老常客了,在游戏中也非常多见,它能够大幅提升游戏画面体验和真实度,使得物体看起来更有细节。 GTA5中的…

第一讲 构图和景别

文章目录 构图中心点构图水平线构图法对称线构图三分线构图法对角线构图引导线构图法前景构图填充构图留白构图重复构图对比构图 景别参考文献 构图 中心点构图 中心构图是将主体放置在画面中心进行构图。这种构图方式的最大优点就在于主体突出、明确,而且画面容易…

Unity景深效果

Unity景深效果 window packagemanager postprocessing installproject面板右键创建post-processing profile主相机设置layer 比如layerA主相机添加组件 post-process layer 里面设置layer为layerA 主相机添加 post-process volume2创建的文件拖到volume上的 profilevolume 勾选…

用Unity实现景深效果

用Unity实现景深效果 景深也是一种非常常见的后处理手段,它用来模拟相机拍摄画面的效果。今天我们讨论如何在Unity中实现它。 简单来说,景深效果可以拆分为两个部分,一个部分是聚焦,使画面中指定的区域清晰显示,另一个…

matlab景深合成算法,简单明了讲解景深合成

看到这样的作品,是不是很疑惑摄影师怎么做到呢,镜头几乎贴着前景拍摄了,前后景都能如此清晰,到底是用多小的光圈才能做到啊? 其实,这样的全景深照片,再小的光圈都无法做到,只能用PS放…

dof景深matlab,景深(DOF)

今天偷偷地背着老板去上本科生的计算机视觉课,然后讲的全部都是照相机的物理知识,作为曾经物理的爱好者,自然非常感兴趣,因此也接触了景深这个概念DOF,英文全称是Depth of Field。 本文着重介绍几个概念性质的东西。 焦…

CSS景深效果

什么是景深 图片在近处很模糊,而在其远处显得很清晰 实现景深效果 初始时 使用景深效果 filter: blur(5px);

matlab景深合成算法,关于景深合成,你想知道的都在这儿!

修图系 来源:极影AdventureX ID:jiyingx 景深合成是现代风光摄影、静物摄影、微距摄影中,被广泛应用的一种前后期技术,可以让我们在复杂条件下,也获得一张从前到后都清晰无比的照片。 以下这篇文章中,极影的姚明来老师,会对景深合成做一个详细的梳理和总结。 上面的这一…