【后端面经】【消息队列】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

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

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

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

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

目录
相关文章
|
2月前
|
消息中间件 缓存 NoSQL
Redis 是一个高性能的键值对存储系统,常用于缓存、消息队列和会话管理等场景。
【10月更文挑战第4天】Redis 是一个高性能的键值对存储系统,常用于缓存、消息队列和会话管理等场景。随着数据增长,有时需要将 Redis 数据导出以进行分析、备份或迁移。本文详细介绍几种导出方法:1)使用 Redis 命令与重定向;2)利用 Redis 的 RDB 和 AOF 持久化功能;3)借助第三方工具如 `redis-dump`。每种方法均附有示例代码,帮助你轻松完成数据导出任务。无论数据量大小,总有一款适合你。
78 6
|
1月前
|
消息中间件
【有奖体验】解锁轻量消息队列(原 MNS)作为云产品间消息通道的典型场景
快来解锁轻量消息队列(原 MNS)作为云产品间消息通道的典型场景,赢丰厚奖品!
|
1月前
|
JavaScript API 开发工具
<大厂实战场景> ~ Flutter&鸿蒙next 解析后端返回的 HTML 数据详解
本文介绍了如何在 Flutter 中解析后端返回的 HTML 数据。首先解释了 HTML 解析的概念,然后详细介绍了使用 `http` 和 `html` 库的步骤,包括添加依赖、获取 HTML 数据、解析 HTML 内容和在 Flutter UI 中显示解析结果。通过具体的代码示例,展示了如何从 URL 获取 HTML 并提取特定信息,如链接列表。希望本文能帮助你在 Flutter 应用中更好地处理 HTML 数据。
113 1
|
2月前
|
存储 缓存 持续交付
后端世界的微妙平衡:性能与可维护性的博弈###
【10月更文挑战第15天】 在软件开发的浩瀚宇宙里,后端开发犹如一颗星辰,既需璀璨夺目以支撑业务辉煌,又得稳若磐石确保系统长青。本文探讨了后端开发中性能优化与代码可维护性之间的微妙平衡,通过实例分析与策略建议,揭示了如何在追求极致速度的同时,保持代码的清晰、可读与易于迭代,实现技术与艺术的和谐共生。我们相信,正如印度圣雄甘地所言:“你必须成为你希望在世界上看到的改变。”开发者在面对复杂系统挑战时,也应主动寻求变革,探索更高效的解决方案。 ###
39 3
|
1月前
|
JSON Dart 数据格式
<大厂实战场景> ~ flutter&鸿蒙next处理后端返回来的数据的转义问题
在 Flutter 应用开发中,处理后端返回的数据是常见任务,尤其涉及转义字符时。本文详细探讨了如何使用 Dart 的 `dart:convert` 库解析包含转义字符的 JSON 数据,并提供了示例代码和常见问题的解决方案,帮助开发者有效处理数据转义问题。
130 0
|
3月前
|
JavaScript 前端开发 数据库
优化后端性能:如何使用异步编程提升系统响应速度
异步编程已成为现代后端系统性能优化的重要策略。通过避免阻塞操作,异步编程可以显著提高系统的响应速度和并发处理能力。本文章深入探讨了异步编程的基本概念,比较了常见的异步编程模型,并通过实际案例演示如何在Node.js和Python中实现异步操作,以提升系统性能。
|
4月前
|
图形学 人工智能 C#
从零起步,到亲手实现:一步步教你用Unity引擎搭建出令人惊叹的3D游戏世界,绝不错过的初学者友好型超详细指南 ——兼探索游戏设计奥秘与实践编程技巧的完美结合之旅
【8月更文挑战第31天】本文介绍如何使用Unity引擎从零开始创建简单的3D游戏世界,涵盖游戏对象创建、物理模拟、用户输入处理及动画效果。Unity是一款强大的跨平台游戏开发工具,支持多种编程语言,具有直观编辑器和丰富文档。文章指导读者创建新项目、添加立方体对象、编写移动脚本,并引入基础动画,帮助初学者快速掌握Unity开发核心概念,迈出游戏制作的第一步。
254 1
|
4月前
|
消息中间件 传感器 缓存
为什么Kafka能秒杀众多消息队列?揭秘它背后的五大性能神器,让你秒懂Kafka的极速之道!
【8月更文挑战第24天】Apache Kafka作为分布式流处理平台的领先者,凭借其出色的性能和扩展能力广受好评。本文通过案例分析,深入探讨Kafka实现高性能的关键因素:分区与并行处理显著提升吞吐量;批量发送结合压缩算法减少网络I/O次数及数据量;顺序写盘与页缓存机制提高写入效率;Zero-Copy技术降低CPU消耗;集群扩展与负载均衡确保系统稳定性和可靠性。这些机制共同作用,使Kafka能够在处理大规模数据流时表现出色。
68 3
|
4月前
|
JavaScript 前端开发
深入理解Node.js事件循环及其对后端性能的影响
【8月更文挑战第31天】 本文将带你一探Node.js的核心概念—事件循环,揭示其工作原理及如何影响后端应用的性能。我们将从基础的事件驱动模型出发,通过代码示例和性能分析,展示如何有效利用事件循环来提升应用响应速度和处理能力。
|
4月前
|
消息中间件 缓存 Java
如何优化大型Java后端系统的性能:从代码到架构
当面对大型Java后端系统时,性能优化不仅仅是简单地提高代码效率或硬件资源的投入,而是涉及到多层次的技术策略。本篇文章将从代码层面的优化到系统架构的调整,详细探讨如何通过多种方式来提升Java后端系统的性能。通过对常见问题的深入分析和实际案例的分享,我们将探索有效的性能优化策略,帮助开发者构建更高效、更可靠的后端系统。

热门文章

最新文章