diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index 3effe1d9b..500db0851 100755 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -2143,6 +2143,7 @@ function getBarBigMarket() { "api/第7节:责任链模式处理抽奖规则.md", "api/第8节:抽奖规则树模型结构设计.md", "api/第9节:模板模式串联抽奖规则.md", + "api/第10节:不超卖库存规则实现.md", "none.md", ] }, diff --git a/docs/.vuepress/public/images/article/project/big-market/big-market-12-01.png b/docs/.vuepress/public/images/article/project/big-market/big-market-12-01.png new file mode 100644 index 000000000..1c4dec17b Binary files /dev/null and b/docs/.vuepress/public/images/article/project/big-market/big-market-12-01.png differ diff --git a/docs/.vuepress/public/images/article/project/big-market/big-market-12-02.png b/docs/.vuepress/public/images/article/project/big-market/big-market-12-02.png new file mode 100644 index 000000000..017bbc968 Binary files /dev/null and b/docs/.vuepress/public/images/article/project/big-market/big-market-12-02.png differ diff --git a/docs/.vuepress/public/images/article/project/big-market/big-market-12-03.png b/docs/.vuepress/public/images/article/project/big-market/big-market-12-03.png new file mode 100644 index 000000000..276620893 Binary files /dev/null and b/docs/.vuepress/public/images/article/project/big-market/big-market-12-03.png differ diff --git a/docs/.vuepress/public/images/article/project/big-market/big-market-12-04.png b/docs/.vuepress/public/images/article/project/big-market/big-market-12-04.png new file mode 100644 index 000000000..c5b2860c6 Binary files /dev/null and b/docs/.vuepress/public/images/article/project/big-market/big-market-12-04.png differ diff --git a/docs/.vuepress/public/images/article/project/big-market/big-market-12-05.png b/docs/.vuepress/public/images/article/project/big-market/big-market-12-05.png new file mode 100644 index 000000000..a4029d00d Binary files /dev/null and b/docs/.vuepress/public/images/article/project/big-market/big-market-12-05.png differ diff --git "a/docs/md/project/big-market/api/\347\254\25410\350\212\202\357\274\232\344\270\215\350\266\205\345\215\226\345\272\223\345\255\230\350\247\204\345\210\231\345\256\236\347\216\260.md" "b/docs/md/project/big-market/api/\347\254\25410\350\212\202\357\274\232\344\270\215\350\266\205\345\215\226\345\272\223\345\255\230\350\247\204\345\210\231\345\256\236\347\216\260.md" new file mode 100644 index 000000000..61ffef6e8 --- /dev/null +++ "b/docs/md/project/big-market/api/\347\254\25410\350\212\202\357\274\232\344\270\215\350\266\205\345\215\226\345\272\223\345\255\230\350\247\204\345\210\231\345\256\236\347\216\260.md" @@ -0,0 +1,40 @@ +--- +title: 第10节:不超卖库存规则实现 +pay: https://t.zsxq.com/17Y1QOlfG +--- + +# 《大营销平台系统设计实现》 - 营销服务 第10节:不超卖库存规则实现 + +作者:小傅哥 +
博客:[https://bugstack.cn](https://bugstack.cn) + +>沉淀、分享、成长,让自己和他人都能有所收获!😄 + +- **本章难度**:★★★☆☆ +- **本章重点**:通过模板模式,整合责任链、规则树,定义出抽奖的标准过程。以及让子类做具体调用功能实现。 +- **课程视频**:[https://t.zsxq.com/17kdkJw1C](https://t.zsxq.com/17kdkJw1C) + +**版权说明**:©本项目与星球签约合作,受[《中华人民共和国著作权法实施条例》](http://www.gov.cn/zhengce/2020-12/26/content_5573623.htm) 版权法保护,禁止任何理由和任何方式公开(public)源码、资料、视频等内容到Github、Gitee等,违反可追究进一步的法律行动。 + +## 一、本章诉求 + +当通过抽奖策略计算完用户可获得的奖品ID后,接下来就需要对这一条奖品记录进行**库存**的扣减操作。只有奖品库存扣减成功,才可以获得奖品ID对应的奖品,否则将走到兜底奖品。 + +除此之外,本节还需要对上一节实现的规则树节点;次数锁、兜底奖品,都会完善。 + +## 二、流程设计 + +**首先对于库存集中扣减类的业务流程,是不能直接用数据库表抗的。** + +比如数据库表有一条记录是库存,如果是通过锁这一条表记录更新库存为10、9、8的话,就会出现大量的用户在应用用获得数据库的连接后,等待前一个用户更新完库表记录后释放锁,让下一个用户进入在扣减。 + +这样随着用户参与量的增加,就会有非常多的用户处于等待状态,而等待的用户是持久数据库的连接的,这个连接资源非常宝贵,你占用了应用中其他的请求就进不来,最终导致一个请求要几分钟才能得到响应。【前台的用户越着急,越疯狂点击,直至越来越卡到崩溃】 + +所以,对于这样的秒杀场景,我们一般都是使用 redis 缓存来处理库存,它只要不超卖就可以。但也确保一点,不要用一条key加锁和等待释放的方式来处理,这样的效率依然是很低的。所以我们要尽可能的考虑分摊竞争,达到无锁化才是分布式架构设计的核心。 + +
+ +
+ +- 如果在前面章节所实现的规则树中,对于库存节点的操作,开发 decr 方式扣减库存。decr 是原子操作,效率非常高。这样要注意,setnx 加锁是一种兜底手段,避免后续有库存的恢复,导致库存从96消耗后又回到了98重复消费。所以对于每个key加锁,98、97、96... 即使有恢复库存也不会导致超卖。【setnx 在 redisson 是用 trySet 实现】 +- 库存消耗完以后,还需要更新库表的数据量。但这会也不能随着用户消耗奖品库存的速率,对数据库表执行扣减操作。所以这里可以通过 Redisson 延迟队列的 + 定时任务的凡是,缓慢消耗队列数据来更新库表数据变化。