海量的用户秒杀请求,本质上是一个排序,先到先得。但是如此之多的请求,注定了有些人是抢不到的,可以在进入上述伪代码 Dao 层之前增加一个计数器进行控制,比如有 50% 的流量将直接告诉其抢购失败,伪代码如下:
count++;
if (count%2==1) {
Thread.sleep(1000);
return new BuyResult("抢购失败");
} else {
return doBuy();
}
这样真的合适吗?
1
invoke 2017-10-26 14:39:52 +08:00
事实上很多队列都是这样的。
直接按照某种规则 告诉你你这次排队没抢到。或者告诉你一个排队次数,但是实际上你是没有购买权限的。以缓解压力。 |
2
airyland 2017-10-26 14:40:44 +08:00
本质上就是限流策略,上面是伪代码具体也可能不是这样。
|
3
ScotGu 2017-10-26 14:43:49 +08:00
看过一个段子,
HR 收集了一批建立,然后分成两份,丢掉一份…… 并说:“来我们公司,首先要有好运气”。 |
5
cnTangLang 2017-10-26 15:01:22 +08:00
你这话题让我想起,12 年京东 618 时秒杀了一个 coach 的太阳镜,好像 1000 多的样子,99 抢购到的。页面写明一个地区的仓库只有一个。结果我付了款了,过了几天也没发货,说库存没了。钱到现在也没退给我。
|
6
est 2017-10-26 15:05:58 +08:00
所以之前 bbs 里的要参与活动的人每人回帖,最后随机抽一个楼层,这样是最公平的。
|
7
jadec0der OP |
9
invoke 2017-10-26 15:13:41 +08:00
@jadec0der
不啊,有些就是这么做的。 之前我抢美图的一个手机也有类似的措施。 更别提最近的大麦网了。直接给你某些时段某些人刷出来的就是个 html 页面。 你能不能抢到,还是排队。根本不是他关心的,因为销售方知道肯定是几秒内就全卖光了。 而且这么处理成本极低,不是吗? |
10
vjnjc 2017-10-26 15:13:49 +08:00
感觉合理啊。
如果改成第一个人抢得到,第二个人抢不到,第三个人抢得到。这种情况也有 [第二个人抢不到,第三个人抢得到] 这种不公平的现象发生。而如果把简单暴力的二分限流去掉的话 doBuy()很容易挂啊,以京东到家的用户来说。 |
11
jadec0der OP @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 |
12
Shura 2017-10-26 15:37:05 +08:00
从概率上看都一样,所以很合理的措施。
|
13
nopy 2017-10-26 15:37:58 +08:00 via Android
小米商城也是这样,之前抢小米 6 怎么抢都是直接排队中,同学进去一抢就抢到了...感觉我的号已经黑号了,直接告诉我不好吗!
|
14
eloah 2017-10-26 15:42:27 +08:00 1
因为它不在乎谁抢到,公平不公平,反正它赚的钱是一样的
它只在乎利用抢来促销而已 |
15
GOOD21 2017-10-26 15:52:51 +08:00
做这个策略一定是触发了某个阈值的,不可能上来就直接 50%这样大概率的“抢购失败”。
能想到的场景,比如用户的抢购请求全部进入 MQ,消费的时候判断一下 Message 的 count 值,超过 xxx,再 50%的失败 |
17
doskoi 2017-10-26 17:07:38 +08:00
如果前面最快抢到的都是非人类行为,一开放没多久,就被黄牛用软件抢光了。
这样还是会跳出来说不公平。 公平是相对于规则所限制的人群的。 |
18
daysv 2017-10-26 17:21:58 +08:00
的确, 这种代码让人难以接受
|
19
6IbA2bj5ip3tK49j 2017-10-26 17:55:54 +08:00
我记得之前看小米的分享,好像是先排满 1000 的队列,其余直接返回失败,然后等着 1000 人下单或者时间达到阈值,再放 1000 人进来,这样循环。
|
21
watzds 2017-10-26 20:43:38 +08:00
@jadec0der 你好,你列的第一篇文章中“增加分配 ID 标志,去掉行锁”,请问你知道什么意思吗?怎么会去掉行锁的
http://www.infoq.com/cn/articles/solution-to-the-architecture-of-spike-system |