秒杀系统中常见问题及解决方案

2023-11-16

秒杀中的常见问题的解决

1)解决超卖的问题

1)Redis预减库存,有一个下单请求过来时预减库存,若减完后的redis库存小于0说明已经卖完,此时直接返回客户端已经卖完。后续使用内存标记,减少Redis访问。若预减库存成功,则异步下单,请求入队列,返回客户端排队中。

2)数据库层面防止超卖:Redis预减库存只是抢到了这个机会,真正是否购买成功还是要等到所有数据库操作的真正成功,即消息队列的消费端是否消费成功。

数据库层面,秒杀的订单表设置唯一索引,防止重复下单。

数据库层面,减库存的时候同时判断此时库存是否大于0。

由于是订单模块和库存模块,涉及到分布式事务的问题,使用seata框架。

2)如何保证Redis的库存与数据库库存的一致性

在我们的项目中,Redis的库存并不是真正的库存,而是用于阻挡多余的下单请求,用于保证有多少秒杀商品库存就放多少个请求到消息队列,大大减少数据库访问。

真正的下单和减库存操作还是操作数据库的。

所以我们不需要保证Redis缓存与数据库的一致性。

3)如何保证MQ不丢失消息

消息丢失的三种情况:

  • **生产者丢失消息:**生产者发送消息到MQ时因为网络问题丢失消息。
  • **MQ丢失消息:**没来得及持久化,就挂掉后消息丢失
  • **消费端丢失消息:**刚从MQ获取消息,没处理完消费者就挂掉了

1 生产者丢失消息的解决方案:

1) rabbitmq提供事务支持,在生产者发送之前开启事务,然后发送消息,如果消息没有成功被rabbitmq接收到,那么生产者会受到异常报错,这时就可以回滚事物,然后尝试重新发送;如果收到了消息,那么就可以提交事物。但是这种方案会阻塞生产者,吞吐量下降。

2)可以将channel开启confirm机制。在生产者哪里设置开启了confirm模式之后,每次写的消息都会分配一个唯一的id,然后写入了rabbitmq之中;**如果rabbitmq没能处理这个消息,会回调你一个nack接口,告诉你这个消息失败了,你可以进行重试。**如果成功发送到mq,也会回调一个ack的接口方法,告诉你成功发送消息。

这里使用方案二!这样吞吐量更高。

2 MQ自己丢失数据的解决方案

设置持久化!持久化有两个步骤:

1)创建queue时设置持久化,但是这时候持久化的是queue的元数据,不会持久化queue里面的数据。

2)发送消息的时候将消息的deliveryMode设置为2,表示将消息持久化。

而且可以将持久化与生产者的confirm机制结合只有持久化成功后才回调ack方法。超时未持久化成功或持久化失败也会回调nack。

3 消费者丢失数据的解决方案:

消费者端丢失数据都是因为开启了rabbitmq的autoACK功能,即消费者获取了数据之后就自动告诉MQ已经消费。

**解决方案:**关闭rabbitmq的autoAck,在确保消息被消费成功之后才发送ACK。消息没有成功消费的话rabbitmq会重发消息,这样能保证消息不会再消费者端丢失。

image-20200712203453995

4)MQ如何保证不重复消费

这里不保证不重复消费,因为保证了消息不丢失就有可能读取重复的消息。这里保证接口的幂等性即可。

在保证幂等性的基础上,因为写入MQ中的数据都有一个唯一编号,当MQ消费成功后立即往redis中写入该编号。在消费端,读取MQ数据后先判断是否已经消费过。

5)如何保证分布式事务

在项目中,MQ消费端需要保证下订单和减库存同时成功或失败,这就涉及到事务的问题。

由于是分布式架构,每一个模块对应自己的数据库,跨库之间的事务就需要分布式事务解决方案。

当然,还有一种简单的方案,秒杀模块单独建立自己的订单表、自己的秒杀商品库存表,即在秒杀下单业务中没有调用其他模块的接口,此时也就简单了,没有分布式事务的存在,采用本地事务解决问题。

在这里,暂且考虑分布式事务,学技术为主。尝试使用SpringCloudAlibaba提供的Seata组件去完成分布式事务,只需要加上@GlobalTransaction注解

Seata solution

通过TC、TM、RM三个组件完成:全局事务管理者、事务发起方、事务的参与方。

Seata事务的执行流程(默认是使用二阶段提交):

  • TM开启分布式事务(TM向TC注册全局事务记录)
  • 按业务场景,编排数据库、服务等事务内资源(RM向TC汇报资源准备状态)
  • TM结束分布式事务,事务一阶段结束(TM通知TC提交/回滚事务)
  • TC汇总事务信息,决定事务是提交还是回滚
  • TC通知所有的RM提交或回滚资源,事务的二阶段结束。

在MQ消费端:

    @RabbitListener(queues = MQConfig.SECKILL_QUEUE)
    public void receiveSkInfo(Channel channel, MSMessage message, @Header(AmqpHeaders.DELIVERY_TAG) long tag) throws IOException {
   
        String courseId = message.getCourseId();
        String id = message.getId();
        String memberId = message.getMemberId();

        //这里不需要判断库存,而是执行SQL的时候检查是否超卖
        // 获取商品的库存
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

秒杀系统中常见问题及解决方案 的相关文章

  • 如何在 Spring Data 中选择不同的结果

    我在使用简单的 Spring Data 查询或 Query 或 QueryDSL 在 Spring Data 中构建查询时遇到问题 如何选择三列 研究 国家 登录 不同的行 并且查询结果将是用户对象类型的列表 Table User Id S
  • 在 mvn 命令中指定 pom.xml 并混合其他项目的目标

    我有多个问题 我可以在 mvn 命令中指定 pom xml 吗 在当前项目上执行 mvn 命令时 我可以混合另一个项目的目标吗 例如 mvn clean otherproject comple otherproject install ot
  • 从 java sdk 向对等方发送提案时出现访问被拒绝错误

    我正在尝试使用以下代码查询区块链并收到访问被拒绝错误 我也遇到同样的错误sendTransactionProposal方法也是如此 UserContext adminUserContext RegisterEnrollUser regist
  • JDK 文档是语言规范的一部分吗?

    只有一名官员Java语言规范 https docs oracle com javase specs jls se8 html index html所有 Java 实现都必须遵守它 API文档怎么样 所有Java实现都需要遵守吗这个版本 ht
  • 如何将 javax.persistence.Column 定义为 Unsigned TINYINT?

    我正在基于 MySQL 数据库中的现有表创建 Java 持久性实体 Bean 使用 NetBeans IDE 8 0 1 我在这个表中遇到了一个字段 其类型为 无符号 TINYINT 3 我发现可以执行以下操作将列的类型定义为 unsign
  • 是否有任何简单(且最新)的 Java 框架可用于在 Swing 应用程序中嵌入电影?

    我正在构建一个小型 Swing 应用程序 我想在其中嵌入一部电影 重要的是 这个应用程序是一个 WebStart 应用程序 并且该库应该能够打包在我启动的 jnlp 中 即 不依赖于本机库 我知道并尝试过 JMF 但我认为与其他框架相比 其
  • 不同类型的数组

    是否可以有一个包含两种不同类型数据的数组 我想要一个包含双精度型和字符串的数组 我尝试过 ArrayList
  • Spring Boot自动装配存储库始终为空[重复]

    这个问题在这里已经有答案了 每次我进入我的服务类时 存储库似乎都没有自动连接 因为它不断抛出 NullPointerException 谁能帮我检查一下我缺少什么吗 这是我的代码 演示应用程序 java package com exampl
  • 在 Wildfly 中与 war 部署共享 util jar 文件

    假设我有一个名为 util jar 的 jar 文件 该 jar 文件主要包含 JPA 实体和一些 util 类 无 EJB 如何使这个 jar 可用于 Wildfly 中部署的所有 war 无需将 jar 放置在 war 的 WEB IN
  • 大数据使用什么数据结构

    我有一个包含一百万行的 Excel 工作表 每行有 100 列 每行代表一个具有 100 个属性的类的实例 列值是这些属性的值 哪种数据结构最适合在这里使用来存储数百万个数据实例 Thanks 这实际上取决于您需要如何访问这些数据以及您想要
  • 如何在代理后面安装 Eclipse Neon

    对于 Neon Eclipse 附带了一个安装程序 我在安装程序中找不到任何配置菜单 我的java版本是 java version java version 1 8 0 72 Java TM SE Runtime Environment b
  • 来自十六进制代码的 Apache POI XSSFColor

    我想将单元格的前景色设置为十六进制代码中的给定颜色 例如 当我尝试将其设置为红色时 style setFillForegroundColor new XSSFColor Color decode FF0000 getIndexed 无论我在
  • 什么时候可以在 Java 中使用 Thead.stop() ?

    Thread stop 的 Java 文档听起来好像如果您调用 Thread stop 世界就会终结 已弃用 这种方法本质上是不安全的 停止线程 Thread stop 导致它解锁所有已锁定的监视器 作为未经检查的 ThreadDeath
  • Spring Security SAML2 使用 G Suite 作为 Idp

    我正在尝试使用 Spring Security 5 3 3 RELEASE 来处理 Spring Boot 应用程序中的 SAML2 身份验证 Spring Boot 应用程序将成为 SP G Suite 将成为 IDP 在我的 Maven
  • 自动生成Flyway的迁移SQL

    当通过 Java 代码添加新模型 字段等时 JPA Hibernate 的自动模式生成是否可以生成新的 Flyway 迁移 捕获自动生成的 SQL 并将其直接保存到新的 Flyway 迁移中 以供审查 编辑 提交到项目存储库 这将很有用 预
  • 流中的非终结符 forEach() ?

    有时 在处理 Java Stream 时 我发现自己需要一个非终端 forEach 来触发副作用但不终止处理 我怀疑我可以用 map item gt f item 之类的方法来做到这一点 其中方法 f 执行副作用并将项目返回到流中 但这似乎
  • java库维护数据库结构

    我的应用程序一直在开发 所以偶尔 当版本升级时 需要创建 更改 删除一些表 修改一些数据等 通常需要执行一些sql代码 是否有一个 Java 库可用于使我的数据库结构保持最新 通过分析类似 db structure version 信息并执
  • 使用布尔值进行冒泡排序以确定数组是否已排序

    我有以下用于冒泡排序的代码 但它根本不排序 如果我删除布尔值那么它工作正常 我知道 由于我的 a 0 小于所有其他元素 因此没有执行交换 任何人都可以帮助我解决这个问题 package com sample public class Bub
  • Resteasy 可以查看 JAX-RS 方法的参数类型吗?

    我们使用 Resteasy 3 0 9 作为 JAX RS Web 服务 最近切换到 3 0 19 我们开始看到很多RESTEASY002142 Multiple resource methods match request警告 例如 我们
  • 如何使用play框架上传多个文件?

    我在用play framework 2 1 2 使用java我正在创建视图来上传多个文件 我的代码在这里 form action routes upload up enctype gt multipart form data

随机推荐

  • input的复选框

  • redis 查看所有的key方式介绍

    本文主要介绍了redis 查看所有的key方式 具有很好的参考价值 希望对大家有所帮助 一起跟随微点阅读小编过来看看吧 可以使用KEYS 命令 1 KEYS pattern 例如 列出所有的key 1 redis gt keys 列出匹配的
  • SpringBoot漏洞大全

    原文出处 SpringBoot漏洞 qq com 前段时间做渗透 发现了一个很眼熟的页面 长这个样子 页面log是 去世界最大的同性交友网github com搜了一下 发现了一个十分详细的文章 存在大量接口信息泄露 成功交差 我打的网站有h
  • 【Python】Windows 11下更改python默认的pip install包安装路径

    Windows 11下更改python默认的pip install包安装路径 看到CSDN和知乎上有很多文章写如何修改pip包的默认安装路径 看了一遍基本都不管用 经过一定时间的摸爬滚打 终于找到了如何修改pip install默认安装路径
  • pychram 安装大三方库总是提示pip版本不匹配

    1 查看pip版本号 terminal终端执行pip list查看当前pip版本号 file settings project pychramproject python interpreter目录下查看搜索pip最新版本号 2 在文件夹地
  • This file isn‘t in your working directory. Teammates you share this request with won‘t be able to us

    postman上传图片文件问题 解决方案 进入设置 file gt settings 上传的文件必须在设置的工作区中 不然会报错 选择body file
  • python入门--Vscode创建python项目

    在VS Code中创建Python项目可以通过以下步骤实现 1 打开VS Code 2 点击左侧的 资源管理器 图标 3 选择一个文件夹 右键点击新建文件夹 命名为你的项目名称 4 打开终端 使用以下命令创建虚拟环境 python m ve
  • 杂项知识

    挂载 img 文件 mount t proc o loop initrd 2 6 23 1 42 fc8 img mnt img mount t debugfs o loop initrd 2 6 23 1 42 fc8 img mnt i
  • CCF-CSP真题《202305-2 矩阵运算》思路+python,c++满分题解

    想查看其他题的真题及题解的同学可以前往查看 CCF CSP真题附题解大全 试题编号 202305 2 试题名称 矩阵运算 时间限制 5 0s 内存限制 512 0MB 问题描述 题目背景 Softmax Q KTd V 是 Transfor
  • 基于openwrt平台搭建局域网技术验证之二

    1 测试目的 验证l2tp服务器模式的可行性 提供vpn l2tp模式的服务器功能 供客户端连接访问内网 2 参考资料 参考连接1 https www jianshu com p ccf8f2cca70e 参考连接2 https openw
  • win10小课堂:如何彻底关闭windows defender

    win10小课堂 如何彻底关闭windows defender Windows10系统中自带了windows defender杀毒软件 但是不少用户对它的评价褒贬不一 其一是扫描的频率太高 占用大量CPU 其二是有些文件 不经过任何提示就直
  • 解决 Command "python setup.py egg_info" failed with error code 1 问题

    解决 Command python setup py egg info failed with error code 1 问题 参考 pip install unroll python setup py egg info failed wi
  • 第七章软件静态测试

    7 1静态测试 静态测试 静态测试是指不运行被测程序本身 通过分析或检查源程序的语法 结构 过程 接口等来检查程序的正确性 其被测对象是各种与软件相关的有必要进行测试的产物 是对需求规格说明书 软件设计说明书 源程序做结构分析 流程图分析
  • Flex 布局

    一 Flex布局 Flex 是Flexible Box的缩写 意思是弹性布局 用来为盒模型布局提供最大的灵活性 任何一个容器都可以指定为flex布局 box display flex 行内元素也可以使用flex布局 box display
  • TCP报文段结构

    TCP报文段结构 源端口号和目的端口号 含义从名字就能看出来 序号和确认号 这二个字段被 TCP 发送方和接收方用来实现可靠数据传输服务 每个字段都是32比特 接收窗口 该字段用于流量控制 大小为16比特 首部长度 该字段指示了以 32 比
  • 12串口通信的定义-2

    1 设备状态信号线 数据装置准备好 DSR 高电平有效 数据终端准备好 DTR 高电平有效 2 请求发送 RTS 当数据终端设备 DTE 要发 允许发送 CTS 是对请求发送信号 RTS 的 3 接收控制线 载波检测 DCD 当数据通信设备
  • ultraiso 下载+破解+Linux U盘启动制作

    1 到官网下载ultraiso https cn ultraiso net xiazai html 2 将该软件安装到windows上 打开输入注册码进行破解 用户名 Guanjiu 注册码 A06C 83A7 701D 6CFC 3 破解
  • 处理雪花算法等造成的精度丢失问题

    前端js精度丢失因为number处理的是16位 雪花算法是19位 在前后端交互的时候就会造成精度损失 方法一 如果是专门针对某一个Id的话 JsonSerialize using ToStringSerializer class 注解可以实
  • c++数据结构第六周(图),深搜、广搜(stl版)

    本方法皆用vector进行邻接表模拟 7 1 图的先深搜索 作者 唐艳琴 单位 中国人民解放军陆军工程大学 输出无向图的给定起点的先深序列 输入格式 输入第一行给出三个正整数 分别表示无向图的节点数N 1
  • 秒杀系统中常见问题及解决方案

    秒杀中的常见问题的解决 1 解决超卖的问题 1 Redis预减库存 有一个下单请求过来时预减库存 若减完后的redis库存小于0说明已经卖完 此时直接返回客户端已经卖完 后续使用内存标记 减少Redis访问 若预减库存成功 则异步下单 请求