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

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

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

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

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

目录
相关文章
|
4天前
|
前端开发 JavaScript
后端开发中的异步编程:提升性能与响应速度的关键
后端开发中的异步编程:提升性能与响应速度的关键
71 0
|
4天前
|
消息中间件 Dubbo Java
Spring全家桶 、Dubbo、分布式、消息队列后端必备全套开源项目
基于 Spring Boot 2.X 版本的深度入门教程。 市面上的 Spring Boot 基础入门文章很多,但是深度入门文章却很少。对于很多开发者来说,入门即是其对某个技术栈的最终理解,一方面是开发者“比较懒”,另一方面是文章作者把 Spring Boot 入门写的太浅,又或者不够全面。
|
4天前
|
消息中间件 缓存 API
【后端面经】【消息队列】22 | 消息队列:消息队列可以用来解决什么问题?-03 扩展性+可用性+事件驱动思想
【5月更文挑战第8天】 本文探讨了扩展性、可用性和事件驱动的概念。扩展性方面,消息队列简化了新下游的接入,而同步调用需要复杂的协调。在保证高可扩展性和研发效率的设计中,若无法使用消息队列,可以提供一致性抽象来减轻接入负担。可用性上,消息队列只需确保消息发送,而同步调用需保证所有下游成功,更易出错。事件驱动是一种通过事件进行组件间通信的架构模式,具有低耦合、高扩展性和高可用性,适合处理复杂流程。结合SAGA的事件驱动方案能实现高级分布式事务管理,即使实时性稍弱,但能保证事务的异步和高效执行。
11 1
|
4天前
|
消息中间件 NoSQL Redis
【后端面经】【消息队列】22 | 消息队列:消息队列可以用来解决什么问题?-01
【5月更文挑战第6天】消息队列的核心特性是异步、削峰和解耦,常用于日志处理和消息通讯,实现事件驱动架构。面试中可能涉及问题包括公司是否使用消息队列、应用场景、优缺点以及延时队列、秒杀架构等。秒杀场景下,消息队列将校验和库存扣减(轻量级)与订单创建(重量级)分隔,减轻系统压力,依赖于Redis性能。使用消息队列能解决高并发、复杂流程同步等问题。
27 0
|
4天前
|
缓存 负载均衡 数据库
优化后端性能:提升Web应用响应速度的关键策略
在当今数字化时代,Web应用的性能对于用户体验至关重要。本文探讨了如何通过优化后端架构和技术手段,提升Web应用的响应速度。从数据库优化、缓存机制到异步处理等多个方面进行了深入分析,并提出了一系列实用的优化策略,以帮助开发者更好地应对日益增长的用户访问量和复杂的业务需求。
19 1
|
4天前
|
消息中间件 微服务
消息队列的适用场景
消息队列的适用场景
14 0
|
4天前
|
SQL 缓存 数据库
后端开发中的数据库优化策略——提高性能和可靠性
在后端开发中,数据库是至关重要的一环。如何优化数据库,提高系统性能和可靠性,一直是后端开发者需要面对的问题。本文将介绍几个常用的数据库优化策略,包括数据结构设计、索引优化、SQL语句优化、缓存优化等方面,希望对后端开发者有所帮助。
32 2
|
4天前
|
监控 Java 开发者
构建高效微服务架构:后端开发的新趋势
【5月更文挑战第13天】随着现代应用的复杂性日益增加,传统的单体应用架构已不足以满足快速迭代和可扩展性的需求。本文将探讨如何通过微服务架构来提升后端开发的效率和系统的可靠性,涵盖微服务设计原则、技术栈选择、部署策略以及维护实践。我们将分析微服务的优势与挑战,并提供一系列实施建议,帮助开发者在构建和维护分布式系统时做出明智决策。
|
4天前
|
存储 监控 API
构建高效微服务架构:后端开发的新趋势
【5月更文挑战第13天】在现代软件开发中,随着业务需求的多样化和开发流程的复杂化,传统的单体应用架构逐渐显得笨重且难以适应快速变化。微服务架构作为一种新兴的分布式系统设计方式,以其灵活性、可扩展性和技术多样性受到广泛关注。本文旨在探讨微服务架构的核心概念、设计原则以及实施策略,为后端开发人员提供一种提升系统性能和开发效率的有效途径。
42 2
|
2天前
|
监控 持续交付 开发者
构建高效微服务架构:后端开发的新范式
【5月更文挑战第18天】 随着现代软件开发的复杂性日益增长,传统的单体应用架构已难以满足快速迭代和灵活部署的需求。本文聚焦于一种新兴的解决方案——微服务架构,探讨其如何为后端开发带来革命性的改变。我们将深入分析微服务的核心概念、优势与挑战,并通过具体案例来阐述如何在实际项目中实施微服务架构。文章旨在为开发者提供一种系统化的方法,帮助他们理解并应用微服务架构,以提升系统的可维护性、扩展性和技术敏捷性。
12 2