基于电商场景的高并发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

相关文章

PostgreSQL简介及实战应用

《PostgreSQL简介及实战应用》PostgreSQL是一种功能强大的开源关系型数据库管理系统,以其稳定性、高性能、扩展性和复杂查询能力在众多项目中得到广泛应用,本文将从基础概念讲起,逐步深入到高... 目录前言1. PostgreSQL基础1.1 PostgreSQL简介1.2 基础语法1.3 数据库

Python WebSockets 库从基础到实战使用举例

《PythonWebSockets库从基础到实战使用举例》WebSocket是一种全双工、持久化的网络通信协议,适用于需要低延迟的应用,如实时聊天、股票行情推送、在线协作、多人游戏等,本文给大家介... 目录1. 引言2. 为什么使用 WebSocket?3. 安装 WebSockets 库4. 使用 We

SpringBoot3匹配Mybatis3的错误与解决方案

《SpringBoot3匹配Mybatis3的错误与解决方案》文章指出SpringBoot3与MyBatis3兼容性问题,因未更新MyBatis-Plus依赖至SpringBoot3专用坐标,导致类冲... 目录SpringBoot3匹配MyBATis3的错误与解决mybatis在SpringBoot3如果

Spring Boot 整合 SSE(Server-Sent Events)实战案例(全网最全)

《SpringBoot整合SSE(Server-SentEvents)实战案例(全网最全)》本文通过实战案例讲解SpringBoot整合SSE技术,涵盖实现原理、代码配置、异常处理及前端交互,... 目录Spring Boot 整合 SSE(Server-Sent Events)1、简述SSE与其他技术的对

深度解析Python yfinance的核心功能和高级用法

《深度解析Pythonyfinance的核心功能和高级用法》yfinance是一个功能强大且易于使用的Python库,用于从YahooFinance获取金融数据,本教程将深入探讨yfinance的核... 目录yfinance 深度解析教程 (python)1. 简介与安装1.1 什么是 yfinance?

Spring Security 前后端分离场景下的会话并发管理

《SpringSecurity前后端分离场景下的会话并发管理》本文介绍了在前后端分离架构下实现SpringSecurity会话并发管理的问题,传统Web开发中只需简单配置sessionManage... 目录背景分析传统 web 开发中的 sessionManagement 入口ConcurrentSess

C++ vector越界问题的完整解决方案

《C++vector越界问题的完整解决方案》在C++开发中,std::vector作为最常用的动态数组容器,其便捷性与性能优势使其成为处理可变长度数据的首选,然而,数组越界访问始终是威胁程序稳定性的... 目录引言一、vector越界的底层原理与危害1.1 越界访问的本质原因1.2 越界访问的实际危害二、基

MyBatis-Plus 与 Spring Boot 集成原理实战示例

《MyBatis-Plus与SpringBoot集成原理实战示例》MyBatis-Plus通过自动配置与核心组件集成SpringBoot实现零配置,提供分页、逻辑删除等插件化功能,增强MyBa... 目录 一、MyBATis-Plus 简介 二、集成方式(Spring Boot)1. 引入依赖 三、核心机制

Python Flask实现定时任务的不同方法详解

《PythonFlask实现定时任务的不同方法详解》在Flask中实现定时任务,最常用的方法是使用APScheduler库,本文将提供一个完整的解决方案,有需要的小伙伴可以跟随小编一起学习一下... 目录完js整实现方案代码解释1. 依赖安装2. 核心组件3. 任务类型4. 任务管理5. 持久化存储生产环境

MySQL 数据库表操作完全指南:创建、读取、更新与删除实战

《MySQL数据库表操作完全指南:创建、读取、更新与删除实战》本文系统讲解MySQL表的增删查改(CURD)操作,涵盖创建、更新、查询、删除及插入查询结果,也是贯穿各类项目开发全流程的基础数据交互原... 目录mysql系列前言一、Create(创建)并插入数据1.1 单行数据 + 全列插入1.2 多行数据