我被京东到家的抢购机制惊呆了,第一个人抢不到,第二个人才能抢到?

2017-10-26 14:24:00 +08:00
 jadec0der

《库存系统难破题?京东到家来分享》

多人同时购买 1 件商品,如何安全地库存扣减?

海量的用户秒杀请求,本质上是一个排序,先到先得。但是如此之多的请求,注定了有些人是抢不到的,可以在进入上述伪代码 Dao 层之前增加一个计数器进行控制,比如有 50% 的流量将直接告诉其抢购失败,伪代码如下:

count++;
if (count%2==1) {
   Thread.sleep(1000);
   return new BuyResult("抢购失败");
} else {
   return doBuy();
}

这样真的合适吗?

7500 次点击
所在节点    分享发现
23 条回复
invoke
2017-10-26 14:39:52 +08:00
事实上很多队列都是这样的。

直接按照某种规则 告诉你你这次排队没抢到。或者告诉你一个排队次数,但是实际上你是没有购买权限的。以缓解压力。
airyland
2017-10-26 14:40:44 +08:00
本质上就是限流策略,上面是伪代码具体也可能不是这样。
ScotGu
2017-10-26 14:43:49 +08:00
看过一个段子,
HR 收集了一批建立,然后分成两份,丢掉一份……
并说:“来我们公司,首先要有好运气”。
ScotGu
2017-10-26 14:44:15 +08:00
@ScotGu #3 更正:
“建立” = “简历”
cnTangLang
2017-10-26 15:01:22 +08:00
你这话题让我想起,12 年京东 618 时秒杀了一个 coach 的太阳镜,好像 1000 多的样子,99 抢购到的。页面写明一个地区的仓库只有一个。结果我付了款了,过了几天也没发货,说库存没了。钱到现在也没退给我。
est
2017-10-26 15:05:58 +08:00
所以之前 bbs 里的要参与活动的人每人回帖,最后随机抽一个楼层,这样是最公平的。
jadec0der
2017-10-26 15:08:32 +08:00
@invoke
@airyland 抢购和抽奖是两码事,先到先得是抢购的基本要求,否则和前端直接 alert("抢购失败") 有什么区别
n2ex2
2017-10-26 15:10:26 +08:00
@ScotGu 还有版本是拿电风扇吹,吹走的简历就扔了
invoke
2017-10-26 15:13:41 +08:00
@jadec0der

不啊,有些就是这么做的。
之前我抢美图的一个手机也有类似的措施。
更别提最近的大麦网了。直接给你某些时段某些人刷出来的就是个 html 页面。
你能不能抢到,还是排队。根本不是他关心的,因为销售方知道肯定是几秒内就全卖光了。
而且这么处理成本极低,不是吗?
vjnjc
2017-10-26 15:13:49 +08:00
感觉合理啊。
如果改成第一个人抢得到,第二个人抢不到,第三个人抢得到。这种情况也有 [第二个人抢不到,第三个人抢得到] 这种不公平的现象发生。而如果把简单暴力的二分限流去掉的话 doBuy()很容易挂啊,以京东到家的用户来说。
jadec0der
2017-10-26 15:31:16 +08:00
@invoke 大麦网确实是技术能力不行,我看了他那个技术总监的文章了,但是京东也这样确实是让友商惊诧。

@vjnjc 是啊,所以正常的秒杀系统都是搞个 FIFO 的排队模块,把先到的那部分放出去而不是随机放出去一部分。比如:
http://www.infoq.com/cn/articles/solution-to-the-architecture-of-spike-system
http://www.infoq.com/cn/articles/flash-deal-architecture-optimization
http://www.infoq.com/cn/articles/yhd-11-11-queuing-system-design/
http://www.infoq.com/cn/articles/how-to-design-a-small-and-beautiful-spike-system
Shura
2017-10-26 15:37:05 +08:00
从概率上看都一样,所以很合理的措施。
nopy
2017-10-26 15:37:58 +08:00
小米商城也是这样,之前抢小米 6 怎么抢都是直接排队中,同学进去一抢就抢到了...感觉我的号已经黑号了,直接告诉我不好吗!
eloah
2017-10-26 15:42:27 +08:00
因为它不在乎谁抢到,公平不公平,反正它赚的钱是一样的
它只在乎利用抢来促销而已
GOOD21
2017-10-26 15:52:51 +08:00
做这个策略一定是触发了某个阈值的,不可能上来就直接 50%这样大概率的“抢购失败”。

能想到的场景,比如用户的抢购请求全部进入 MQ,消费的时候判断一下 Message 的 count 值,超过 xxx,再 50%的失败
jadec0der
2017-10-26 16:29:31 +08:00
@GOOD21 你看我发的那几个链接,正常设计都是阈值比库存总量大一些,这样超过阈值直接失败就可以了。
doskoi
2017-10-26 17:07:38 +08:00
如果前面最快抢到的都是非人类行为,一开放没多久,就被黄牛用软件抢光了。
这样还是会跳出来说不公平。

公平是相对于规则所限制的人群的。
daysv
2017-10-26 17:21:58 +08:00
的确, 这种代码让人难以接受
xgfan
2017-10-26 17:55:54 +08:00
我记得之前看小米的分享,好像是先排满 1000 的队列,其余直接返回失败,然后等着 1000 人下单或者时间达到阈值,再放 1000 人进来,这样循环。
kwkwkkk
2017-10-26 18:06:52 +08:00
@ScotGu 让我想到华为校招了,当年随机抽取简历。。。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/400944

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX