【后端面经】【消息队列】22 | 消息队列:消息队列可以用来解决什么问题?-02 超时场景+性能问题

简介: 【5月更文挑战第7天】本文介绍了电商中订单超时取消的处理方法,通过使用消息队列实现延时消息。当订单30分钟后未支付,消息队列将触发取消操作,但需注意并发问题,如采用分布式锁或乐观锁避免并发更新订单状态。乐观锁确保只有订单状态为未支付时才允许支付。主流消息队列如RocketMQ支持延迟消息,而Kafka不支持。使用消息队列的好处在于解耦和提高系统性能、扩展性和可用性。同步调用会导致性能下降,因为必须等待所有调用完成。并发调用虽可提升性能,但仍逊于消息队列,且无法解决扩展性和可用性问题。

订单超时取消

在电商里面,如果用户下单后一直没有支付,这个订单就会被取消,从而释放库存。

订单超时取消在行业里有很多种做法,在这里仅介绍使用消息队列的解决方案。

需要使用延时消息,在发送者发送以后,一段时间后,消费者才能消费的消息。

2024-05-08-20-34-39-image.png

消息队列也可以用于订单超时取消这种场景,在这种场景下,可以准备一个延时队列,比如超时时间是30min,延时就是30min。

在消费的时候要注意并发问题,也就是在30分钟这一时刻,一边用户支付,一边消费者也消费超时消息,就会有并发问题。解决思路有很多,比如用分布式锁、乐观锁,也可以使用SELECT FOR UPDATE锁住订单,防止并发操作。

2024-05-08-20-36-28-image.png

在解决并发问题的思路里,提到了数据库部分的SELECT FOR UPDATE 和 乐观锁。

乐观锁方案简单来说就是把订单更新为超时状态的时候,需要确保原始状态是未支付

UPDATE `order` SET `status`="超时未支付" 
WHERE `id`=123 AND `status`="未支付"

在支付那边也要确保只有status是未支付的时候才能发起支付。

备注:目前主流的消息队列里RocketMQ是支持延迟消息的,有插件。但是Kafka不支持。所以当面试官问你“为什么不用 Kafka”这种问题,你可以把Kafka 不支持延时消息作为理由之一。

亮点

回答为什么一定要使用消息队列?也就是不用消息队列会怎么样,用了有什么好处?

从创建订单的场景看,在订单创建后,要通知很多下游,常见的做法是发送一个订单创建的消息,然后关心订单创建的业务方各自去订阅这个消息。

-- 那为什么订单服务不直接调用各个业务方呢?

2024-05-08-20-41-48-image.png

2024-05-08-20-41-41-image.png

-- 类似的场景还有,在消息通讯里,为什么服务端不直接把消息转发给各个接收者呢?

2024-05-08-20-42-23-image.png

本质问题是:在这个业务场景下,不异步、不解耦或不削峰会有什么问题?

答案是:性能差、扩展性差、可用性差

不太好的回答就是耦合严重,面试官希望深入解释的是耦合严重会带来什么后果。

同步调用方案相比引入消息队列来说有三个缺陷,分别是性能差、可扩展性差和可用性差

性能差

性能差是因为你需要停下来等全部调用完成才可以返回响应。

2024-05-08-21-03-54-image.png

业务方必须停下来等待结果,如果我这里需要通知三个下游,那么就需要发起三次调用,并且等它们各自的结果返回之后才能继续往下执行,或者返回响应,这样性能太差了。

紧接着面试官就可能和你抬扛:“如果我并发调用呢?性能也很好啊!”他隐含的意思就是你可以开启多个线程或者协程,并发调用所有的下游。

2024-05-08-21-04-16-image.png

但是,即便是并发调用性能也比使用消息队列差

并发调用相比于使用消息队列,性能也更差。在并发调用的情况下,性能取决于最坏的那个同步调用什么时候返回结果。而正常我们丢一个消息到消息中间件上是很快的。

紧接着你可以补充一点,引出扩展性和可用性的话题。

并且,即便并发调用的性能损耗是可以接受的,但是扩展性和可用性还是解决不了。

目录
相关文章
|
16天前
|
JavaScript 前端开发 数据库
优化后端性能:如何使用异步编程提升系统响应速度
异步编程已成为现代后端系统性能优化的重要策略。通过避免阻塞操作,异步编程可以显著提高系统的响应速度和并发处理能力。本文章深入探讨了异步编程的基本概念,比较了常见的异步编程模型,并通过实际案例演示如何在Node.js和Python中实现异步操作,以提升系统性能。
|
2月前
|
图形学 人工智能 C#
从零起步,到亲手实现:一步步教你用Unity引擎搭建出令人惊叹的3D游戏世界,绝不错过的初学者友好型超详细指南 ——兼探索游戏设计奥秘与实践编程技巧的完美结合之旅
【8月更文挑战第31天】本文介绍如何使用Unity引擎从零开始创建简单的3D游戏世界,涵盖游戏对象创建、物理模拟、用户输入处理及动画效果。Unity是一款强大的跨平台游戏开发工具,支持多种编程语言,具有直观编辑器和丰富文档。文章指导读者创建新项目、添加立方体对象、编写移动脚本,并引入基础动画,帮助初学者快速掌握Unity开发核心概念,迈出游戏制作的第一步。
48 1
|
2月前
|
消息中间件 传感器 缓存
为什么Kafka能秒杀众多消息队列?揭秘它背后的五大性能神器,让你秒懂Kafka的极速之道!
【8月更文挑战第24天】Apache Kafka作为分布式流处理平台的领先者,凭借其出色的性能和扩展能力广受好评。本文通过案例分析,深入探讨Kafka实现高性能的关键因素:分区与并行处理显著提升吞吐量;批量发送结合压缩算法减少网络I/O次数及数据量;顺序写盘与页缓存机制提高写入效率;Zero-Copy技术降低CPU消耗;集群扩展与负载均衡确保系统稳定性和可靠性。这些机制共同作用,使Kafka能够在处理大规模数据流时表现出色。
41 3
|
2月前
|
JavaScript 前端开发
深入理解Node.js事件循环及其对后端性能的影响
【8月更文挑战第31天】 本文将带你一探Node.js的核心概念—事件循环,揭示其工作原理及如何影响后端应用的性能。我们将从基础的事件驱动模型出发,通过代码示例和性能分析,展示如何有效利用事件循环来提升应用响应速度和处理能力。
|
2月前
|
消息中间件 缓存 Java
如何优化大型Java后端系统的性能:从代码到架构
当面对大型Java后端系统时,性能优化不仅仅是简单地提高代码效率或硬件资源的投入,而是涉及到多层次的技术策略。本篇文章将从代码层面的优化到系统架构的调整,详细探讨如何通过多种方式来提升Java后端系统的性能。通过对常见问题的深入分析和实际案例的分享,我们将探索有效的性能优化策略,帮助开发者构建更高效、更可靠的后端系统。
|
3月前
|
消息中间件 Java 物联网
消息队列 MQ操作报错合集之建立连接时发生了超时错误,该如何解决
消息队列(MQ)是一种用于异步通信和解耦的应用程序间消息传递的服务,广泛应用于分布式系统中。针对不同的MQ产品,如阿里云的RocketMQ、RabbitMQ等,它们在实现上述场景时可能会有不同的特性和优势,比如RocketMQ强调高吞吐量、低延迟和高可用性,适合大规模分布式系统;而RabbitMQ则以其灵活的路由规则和丰富的协议支持受到青睐。下面是一些常见的消息队列MQ产品的使用场景合集,这些场景涵盖了多种行业和业务需求。
消息队列 MQ操作报错合集之建立连接时发生了超时错误,该如何解决
|
2月前
|
消息中间件 存储 Kafka
现代消息队列与云存储问题之Kafka在海量队列场景下存在性能的问题如何解决
现代消息队列与云存储问题之Kafka在海量队列场景下存在性能的问题如何解决
|
3月前
|
消息中间件 存储 RocketMQ
MetaQ/RocketMQ 原理问题之在解耦场景中,消息队列工作的问题如何解决
MetaQ/RocketMQ 原理问题之在解耦场景中,消息队列工作的问题如何解决
|
4月前
|
NoSQL 消息中间件 数据库
|
4月前
|
消息中间件 Java Spring
JavaWeb后端开发Spring框架之消息 消息队列案例--订单短信通知
JavaWeb后端开发Spring框架之消息 消息队列案例--订单短信通知
34 0

热门文章

最新文章

下一篇
无影云桌面