基于电商场景的高并发RocketMQ实战-发送优惠券流程解析、生产环境的落库与定时推送解决方案

本文主要是介绍基于电商场景的高并发RocketMQ实战-发送优惠券流程解析、生产环境的落库与定时推送解决方案,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

🌈🌈🌈🌈🌈🌈🌈🌈
欢迎关注公众号(通过文章导读关注),发送【资料】可领取 深入理解 Redis 系列文章结合电商场景讲解 Redis 使用场景中间件系列笔记编程高频电子书
【11来了】文章导读地址:点击查看文章导读!
🍁🍁🍁🍁🍁🍁🍁🍁

发送优惠券流程【落库+定时推送生产环境解决方案】

首先,还是先了解业务逻辑的背景,对于系统中不活跃的用户,需要通过给这些用户发送优惠券来激活这些用户的消费,那么在给这些用户发送优惠券的时候,可能并不想立即就发送,而是定时发送,那么这里的解决方案就是通过先将优惠券信息 落库,再通过 xxl-job 去扫描这个表执行优惠券推送给用户的任务

那么整个发送优惠券的流程如下:

这里先主要说一下如何对定时任务进行落库的,首先创建了一个优惠券,将这个优惠券进行推送,那么既然定时推送,就需要在优惠券的信息中定义 3 个数据:定时推送开始时间定时推送结束时间推送轮次,推送轮次表示在开始推送到推送结束这之间需要推送多少次

定时任务的落库就是通过这 3 个数据计算出来每一次推送的时间点,每一次推送都作为一个定时任务落库,如果 推送轮次 = 1,那么直接将 定时推送的开始时间 作为任务执行时间即可,如果 推送轮次 > 1,那么需要通过 (定时推送结束时间 - 定时推送开始时间) / 推送轮次 来拿到每次任务的执行时间,将每次需要执行的定时任务都落库存储即可

至此,给不活跃用户发送优惠券的主流程就已经结束了,接下来就进入到 xxl-job 去扫描定时任务并执行的阶段,xxl-job 执行流程如下:

  1. 首先去数据库中扫描 执行时间 <= 当前时间 并且 没有执行过 的任务

  2. 将该定时执行任务发送到 MQ 中,等待消费者消费

    这里推送定时任务到 MQ 中,还是需要进行 分片 + 多线程进行推送 来提升推送速度(因为需要推送的用户数量太庞大),分片 + 多线程优化推送的流程和上边 创建促销活动 时是一样的,这里就不重复说了

  3. 发送到 MQ 之后,将该任务状态修改为 已执行,并修改数据库

总结来说,定时发送优惠券就是先将定时任务落库,再通过 xxl-job 去扫描定时任务进行推送即可

大量定时任务通过 xxljob 执行【优化方案】

这里讲的大量定时任务是什么呢?

首先,还是说一下业务背景,对于热门商品的推送在电商场景中是很常见的,那么每一个热门商品所需要推送给的用户可能都是不同的,因此会通过另外一个推荐系统,计算出大量的热门商品,之后再对这些热门商品进行用户的推送,而热门商品推送给用户一般也是定时进行推送的,这里使用了 xxl-job 来进行实现定时的推送,但是这里需要推送的商品数量也是很多的,单靠一个机器进行定时推送速度很慢,那么这里就通过任务分片来加快推送的速度

先获取 当前任务的分片索引,再获取 总共任务分片的数量,之后可以通过需要推送商品的 id 来进行分片处理,下边写一个简单的伪代码:

@XxlJob("job")
public void job() {// 获取 xxlJob 中当前任务的分片索引int shardIndex = Optional.of(XxlJobHelper.getShardIndex()).orElse(0);// 获取 xxlJob 中当前任务的总分片数量int totalShardNum = Optional.of(XxlJobHelper.getShardTotal()).orElse(0);// 循环任务,推送到 MQ 中for (Good good : goods) {Long goodId = good.getId();// 计算出商品 id 应该被哪一个任务分片处理int curNo = goodId.hashCode() % totalShardNum;// 如果当前任务分片索引和商品需要被处理的分片索引不同,就不处理,直接跳过if (curNo != shardIndex) {continue;}}
}

需要推送的商品和任务执行的分片对应关系如下:

在这里插入图片描述

项目中为什么要引入 RocketMQ?【面试】

在面试的时候,讲项目要讲整个业务闭环讲清楚,以及引入中间件的需要和背景

项目中引入 RocketMQ 的优点在于:

  • 削峰填谷
  • 异步优化
  • 高扩展性

首先对于 削峰填谷,在 RocketMQ 中通过减少消费者的线程数或者限制消费者的消费能力来进行削峰,在系统低负载期间,通过增加消费者的线程数量来进行填谷,可以保证系统在运行期间,负载基本上处于一个稳定的状态,不会突然因为极高的负载而出现意外情况

其次是异步优化,这是很关键的,比如在运营人员创建完促销活动之后,需要对用户进行活动的推送,那么这个推送是很消耗时间的,因此需要将推送的任务在创建促销活动中异步出去,将耗时任务从主流程中剥离出去慢慢执行,不影响主流程的执行时间

对于高扩展性,在用户创建完订单之后,如果取消订单,在不使用 MQ 的情况下,需要在取消订单的逻辑中去一个一个执行取消订单后需要执行的操作,如下:

  • 库存系统释放库存
  • 返还用户积分
  • 释放用户使用的优惠券

这样会导致取消订单的动作和其他业务耦合度很高,如果使用 MQ 之后,只需要在这三个地方关注订单取消的事件,不需要将取消订单中做很多耦合的操作

如果后续需要对取消订单做出调整,只用在订阅【取消订单】事件的位置修改代码即可

这篇关于基于电商场景的高并发RocketMQ实战-发送优惠券流程解析、生产环境的落库与定时推送解决方案的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/565415

相关文章

SpringBoot应用中出现的Full GC问题的场景与解决

《SpringBoot应用中出现的FullGC问题的场景与解决》这篇文章主要为大家详细介绍了SpringBoot应用中出现的FullGC问题的场景与解决方法,文中的示例代码讲解详细,感兴趣的小伙伴可... 目录Full GC的原理与触发条件原理触发条件对Spring Boot应用的影响示例代码优化建议结论F

Vuex Actions多参数传递的解决方案

《VuexActions多参数传递的解决方案》在Vuex中,actions的设计默认只支持单个参数传递,这有时会限制我们的使用场景,下面我将详细介绍几种处理多参数传递的解决方案,从基础到高级,... 目录一、对象封装法(推荐)二、参数解构法三、柯里化函数法四、Payload 工厂函数五、TypeScript

SpringBoot条件注解核心作用与使用场景详解

《SpringBoot条件注解核心作用与使用场景详解》SpringBoot的条件注解为开发者提供了强大的动态配置能力,理解其原理和适用场景是构建灵活、可扩展应用的关键,本文将系统梳理所有常用的条件注... 目录引言一、条件注解的核心机制二、SpringBoot内置条件注解详解1、@ConditionalOn

SpringQuartz定时任务核心组件JobDetail与Trigger配置

《SpringQuartz定时任务核心组件JobDetail与Trigger配置》Spring框架与Quartz调度器的集成提供了强大而灵活的定时任务解决方案,本文主要介绍了SpringQuartz定... 目录引言一、Spring Quartz基础架构1.1 核心组件概述1.2 Spring集成优势二、J

MySQL中FIND_IN_SET函数与INSTR函数用法解析

《MySQL中FIND_IN_SET函数与INSTR函数用法解析》:本文主要介绍MySQL中FIND_IN_SET函数与INSTR函数用法解析,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一... 目录一、功能定义与语法1、FIND_IN_SET函数2、INSTR函数二、本质区别对比三、实际场景案例分

Python 迭代器和生成器概念及场景分析

《Python迭代器和生成器概念及场景分析》yield是Python中实现惰性计算和协程的核心工具,结合send()、throw()、close()等方法,能够构建高效、灵活的数据流和控制流模型,这... 目录迭代器的介绍自定义迭代器省略的迭代器生产器的介绍yield的普通用法yield的高级用法yidle

Redis在windows环境下如何启动

《Redis在windows环境下如何启动》:本文主要介绍Redis在windows环境下如何启动的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Redis在Windows环境下启动1.在redis的安装目录下2.输入·redis-server.exe

Pytest多环境切换的常见方法介绍

《Pytest多环境切换的常见方法介绍》Pytest作为自动化测试的主力框架,如何实现本地、测试、预发、生产环境的灵活切换,本文总结了通过pytest框架实现自由环境切换的几种方法,大家可以根据需要进... 目录1.pytest-base-url2.hooks函数3.yml和fixture结论你是否也遇到过

jupyter代码块没有运行图标的解决方案

《jupyter代码块没有运行图标的解决方案》:本文主要介绍jupyter代码块没有运行图标的解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录jupyter代码块没有运行图标的解决1.找到Jupyter notebook的系统配置文件2.这时候一般会搜索到

java实现延迟/超时/定时问题

《java实现延迟/超时/定时问题》:本文主要介绍java实现延迟/超时/定时问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java实现延迟/超时/定时java 每间隔5秒执行一次,一共执行5次然后结束scheduleAtFixedRate 和 schedu