聊聊高并发下库存加减那些事儿——“异步扣减库存”

640?wx_fmt=png

聊聊高并发下库存加减那些事儿

不定期福利发放哦

640?wx_fmt=gif
640?wx_fmt=gif
聊聊高并发下库存加减那些事儿
背景

     一般在日常开发中经常会遇到打折促销,秒杀活动,就如拼多多最近的4999抢券买爱疯11促销活动,毕竟谁的钱也不是大风刮来的,有秒杀有促销必定带来大量用户,而这类活动往往支撑着公司重要营销策略,所以保证系统在高并发下不出异常非常关键,这其中棘手的便是如何在高并发下高效的处理库存数据。今天就来聊聊高并发下库存加减那些事儿。

640?wx_fmt=png
常规做法

首先我们要明确重要的一点是减库存是需要顺序的,而需要顺序就意味着不能有并发加减库存的操作,为了实现顺序,一般做法都是将多线程强行变为单线程实现同步操作或者所说的顺序,将多线程变为单线程方案普遍做法便是使用锁或者借助队列。另一方面由于大型互联网应用面向大量用户所以都是大型分布式加集群作为最基础的架构,而由于架构原因,往常所使用的lock或者Synchronized进程锁关键字失去了意义(只能锁住当前Web程序代码块,但无法锁住集群中其他Web程序)。此时我们便要借助分布式锁或者MQ组件来达到跨进程跨主机的单线程效果。

接下来我们以ABC下单减库为例说明分布式下的减库存场景

ABC同时发起库存减1的请求

服务器接收到三个减库存操作,利用分布式锁锁住了减库存的逻辑,每次只限一个请求操作.对A请求进行库存减1操作后,再对B进行操作,one by one 以此类推。

640?wx_fmt=png

目前减库存操作运行很好,不会发生超卖情况,老板再也不担心程序员败家了。但是以上减库存的逻辑有个很大的问题便是由于强行将多线程请求变为单线程,不可避免的导致排队的发生,这样会发生什么情况呢?

越后进分布式锁或者队列的请求他需要的响应时间越久因为他的响应时间是前面所有请求的响应时间之和。当然有人会说增加配置或者在redis中减库存再利用rabbitmq将结果同步到数据库中,由于操作内存中的数据让减库存操作响应加快,这的确对单次的减库存有效,但是随着并发提高,单次减库存响应时间的优化必将遇到瓶颈。依然没有解决高并发下所有人必须强行排队导致的问题。那有没有那种又顺序执行又能相对的并行加减库存操作呢?

并行异步减库存

减库存必定是顺序排队的,这毋庸置疑,但是有没有办法可以加快这个排队呢,答案是有的!

640?wx_fmt=png

只有将同步减库存逻辑变为异步才能从根本解决排队问题。但是有人会说这与库存操作的逻辑(同步顺序排队)冲突。

其实这里所说的异步是相对的,什么意思呢?

首先全局库存是必须顺序操作的,但是如果我们把库存分割成N块,每一块内部是顺序的,但是每一块彼此之间又是异步的。这样就很好的解决了库存顺序执行的逻辑又减轻了排队的影响。有人会问这里是如何减轻的呢?首先来给减库存算一笔响应时间的账:

假设每个减库存操作的响应时间优化到50毫秒,并发2000,按照常规做法加全局锁那第2000个人的响应时间便是前面1999个用户的响应时间加他自己的50毫秒之和为100秒。100秒的响应可能用户早就心里默默诅咒你了。而且这已经是非常理想化的单次响应时间了。如果有人说可以优化到2毫秒就不会超时了。。麻烦带上键盘去微博杠吧。。

如果使用第二种方案假设三个用户请求减库存操作,完全可以让三个请求进三个不同的锁去扣减各自的库存数,此时三人没有排队可以保证他们同时减库存,而又不影响库存总数的准确性,因为三个请求操作的是各自锁所维护的库存数。随着业务增长,库存总数的分割可以不断细分直到缩短响应时间到合理范围,而这个库存总数的分割很好的保证了不会遇到瓶颈。但是由于这种业务架构的设计,导致业务不得不变得复杂,可以看到我们在进入分布式锁之前有一个称为库存总数协调器的模块,这个模块是用来做什么的呢?

首先我们把库存分割成多块后解决的首要问题便是如何让请求均匀的依次进入每一个分布式锁中进而操作当前锁所负责的库存数。

库存协调器的逻辑完全看各位自己业务模型来决定,你可以用雪花算法均匀分布也可使用ip或者用户标识取余去覆盖到每一个锁,总之实现方式看业务情况来决定,当然了很大几率会出现有的库存块内的库存总数消耗完了但有的还剩余,所以库存协调器一定要考虑到这类情况及时将库存较多的库存块内的库存数分散给其他库存块,以达到多线程减库存的效果。

从示例图中可以看到引入了rabbitmq,他在当前整个业务架构中的作用主要是每一个分布式锁处理完当前库存块的库存后要将当前加减的数量丢给消息队列,由消费端慢慢消化这些操作到数据库。

总结

其实解决高并发业务只要你遵循让一个变成多个的思路,很多都有解决办法等着你

提前预祝中华人民共和国成立70周年smiley_0.png 国庆快乐。。

640?wx_fmt=png

640?wx_fmt=png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/313654.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

什么是MVC

什么是MVC? MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范。 用一种业务逻辑、数据、界面显示分离的方法,将业务逻辑聚集到一个部件里面&#xf…

P3242 [HNOI2015] 接水果(整体二分、扫描线)

P3242 [HNOI2015] 接水果 给定一棵树,定义给定了ppp个盘子,每个盘子是树上u,vu, vu,v两点的路径,且盘子有权值,定义水果,水果也是树上u,vu, vu,v两点间的路径。 有qqq个询问,每次给定u,v,ku, v, ku,v,k&a…

SpringMVC 、Struts的区别

先说结论:目前Spring MVC已经一统江山,Struts正在被抛弃 1、Spring MVC原理 Spring 体系: Spring MVC工作流程图 SpringMVC的工作流程描述 1. 用户向服务器发送请求,请求被Spring前端控制Servelt DispatcherServlet捕获&#x…

P3700 [CQOI2017]小Q的表格(反演、分块)

P3700 [CQOI2017]小Q的表格 给定一个大小为nnn \times nnn的表格,初始时i,ji, ji,j位置上填的是f(i,j)ijf(i, j) i \times jf(i,j)ij,有mmm个操作,每次操作给定a,b,x,ka, b, x, ka,b,x,k,把格子a,ba, ba,b上的值改成xxx&#xf…

基于Asp.Net Core MVC和AdminLTE的响应式管理后台之侧边栏处理

说明:.NET Core版本为:2.2 AdminLTE版本为:2.4.18 Bootstrap版本为:3.4.1 font-awesome版本为:4.7.01、新建项目:AdminLteDemo,添加区域Admin 在Areas/Admin/Views文件夹添加文件并分别添加如下代码:_ViewImports.cshtmladdTagHel…

Spring boot——起步依赖

一、起步依赖 1、是什么 本质上是一个Maven项目对象模型(Project Object Model, POM), 定义了对其他库的传递依赖,这些东西加在一起即支持某项功能。 比如: spring-boot-dependencies^ spring-boot-pare…

[翻译] ASP.NET Core 3.0 的新增功能

全文翻译自微软官方文档英文版 Whats new in ASP.NET Core 3.0本文重点介绍了 ASP.NET Core 3.0 中最重要的更改,并提供相关文档的连接。BlazorBlazor 是 ASP.NET Core 中的一个新的框架,用于使用 .NET 构建交互式的客户端 Web UI:使用 C# 而…

Convolution(2021牛客暑期多校训练营4)

Convolution 定义a⊕babgcd⁡(a,b)2a \oplus b \frac{a \times b}{\gcd(a, b) ^ 2}a⊕bgcd(a,b)2ab​,bm∑i1n∑j1naijc[i⊕jm]b_m \sum\limits_{i 1} ^{n} \sum\limits_{j 1} ^{n}a_i \times j ^ c [i \oplus j m]bm​i1∑n​j1∑n​ai​jc[i⊕jm]&#xff0…

Sprig boot自动配置

1、概述 Spring Boot是Spring旗下众多的子项目之一,其理念是约定优于配置,它通过实现了自动配置(大多数用户平时习惯设置的配置作为默认配置)的功能来为用户快速构建出标准化的应用。Spring Boot的特点可以概述为如下几点&#x…

E. Mocha and Stars(莫比乌斯反演、简单dp)

E. Mocha and Stars ∑a1l1r1∑a2l2r2⋯∑anlnrn[a1a2⋯an≤m][gcd⁡(a1,a2,…,an)1]\sum_{a_1 l_1} ^{r_1} \sum_{a_2 l_2} ^{r_2} \dots \sum_{a_n l_n} ^{r_n} [a_1 a_2 \dots a_n \le m][\gcd(a_1, a_2, \dots, a_n) 1]\\ a1​l1​∑r1​​a2​l2​∑r2​​⋯an​ln…

.NET Core 3.0稳定版发布

一年一度的 .NET 开发者盛会 .NET Conf 2019 已正式开始了(举办时间为 9.23-9.25)。大会第一天最重磅也是最激动人心的消息莫过于 .NET Core 3.0 稳定版的发布。.NET 项目管理总监 Scott Hunter 在大会宣布了这则消息,并在主题演讲环节围绕 .…

深入理解 Spring Boot Starters 原理(手写Spring boot Start)

一、Spring Boot Starter诞生原因 Spring Boot Starter是在SpringBoot组件中被提出来的一种概念,stackoverflow上面已经有人概括了这个starter是什么东西,想看完整的回答戳这里 Starter POMs are a set of convenient dependency descriptors that you …

FFT字符串匹配(解决通配符问题)

FFT字符串匹配 定义字符串下标从000,开始,有文本串AAA长度为nnn,模式串BBB长度为mmm,我们可以考虑一个函数f(x,y)A(x)−B(y)f(x, y) A(x) - B(y)f(x,y)A(x)−B(y)。 我们设F(x)(x≥m−1)∑i0m−1f(x−m1i,i)F(x)(x \ge m - 1) …

记一次中小公司的研发问题

作者:zollty,资深程序员和架构师,私底下是个爱折腾的技术极客,架构师社区合伙人!一、一些不好的现状,及对应的改进方法1、前后端代码绑定在一起,很难维护,前端UI做得太差&#xff0c…

命令行操作mysql

1、通过命令行连接mysql: 1、输入命令:mysql -h localhost(服务IP地址) -u root(用户名) -P 3306(服务端口)-p 2、输入密码 2、显示数据库、表: show databases; //…

2021CCPC华为云挑战赛:HDU 7091 重叠的子串(SAM + 线段树合并)

重叠的子串 给定一个长度为n(1≤∣s∣≤105)n(1 \le \mid s \mid \le 10 ^ 5)n(1≤∣s∣≤105)的只由小写字母构成的字符串sss,有m,(1≤m≤106)m, (1 \le m \le 10 ^ 6)m,(1≤m≤106)个询问: 每次询问给定l,rl, rl,r,问sss是否存在一个字串…

ASP.NET Core 3.0 使用gRPC

一.简介gRPC 是一个由Google开源的,跨语言的,高性能的远程过程调用(RPC)框架。gRPC使客户端和服务端应用程序可以透明地进行通信,并简化了连接系统的构建。它使用HTTP/2作为通信协议,使用 Protocol Buffers…

mysql 1030 error:Got error 28 from storage engine

最近生产应用连不上生产环境数据库,使用命令行连上去之后,执行命令出现1030 error。 故Google之,解决方案如下。 mysql 1030 error 是因为没有足够的空间,清理磁盘空间即可恢复正常使用。 然后追踪发现,磁盘空间为99G&…

Codeforces Round #739 (Div. 3)(AK实况)

Codeforces Round #739 (Div. 3) A. Dislike of Threes 找到第kkk个既不是333的倍数&#xff0c;个位数上也不是333的数&#xff0c;也已预处理然后O(1)O(1)O(1)输出&#xff0c;也可直接forforfor循环暴力。 #include <bits/stdc.h>using namespace std;int main() {/…

利用Helm简化Kubernetes应用部署(2)

目录定义Charts 使用Helm部署Demo Helm常用操作命令 定义Charts回到之前的“charts”目录&#xff0c;我们依次进行解读并进行简单的修改。Chart.yaml配置示例&#xff1a;apiVersion: v1 appVersion: "1.1" description: A demo Helm chart for Kubernetes name:…