我们给新用户送一笔免费额度。为了防止有人反复注册白嫖,加了三道闸。
后来三道全拆了。
三道闸和它们的误伤
① 同一个公司域名,第二个注册的人减半额度。
想拦的是「同一个人换个前缀再注册一次」。
实际误伤的是同事。 一家公司来了三个人各自注册,从第二个开始就被削——而他们是最理想的那种客户。
② 同一份文件只吃一次免费额度。
想拦的是「同一段素材反复跑」。
实际误伤的是重传。 上传失败了再传一次、传错了删掉重传、想换个设置再跑一遍——这些都是正常操作。
③ 同一个网络出口,第三个注册的账号零额度。
想拦的是「一个人批量注册」。
实际误伤的是共用出口的办公室。 一间办公室几十个人共用一个对外地址,第三个想试试我们产品的人,得到的是零。
共同的毛病
把三条摆在一起看,它们有同一个结构:
拦的是用户本来也不会去做的事,误伤的是用户天天在做的事。
而且误伤是不可见的:
- 被拦住的人不会来投诉。他不知道自己本该有多少额度,他只会觉得「这个产品好像没什么诚意」,然后走掉
- 我们这边看不到任何信号。没有报错、没有工单、没有异常曲线
一个只有坏处看得见、好处看不见的机制,是最难被发现该拆的。
拆的时候留了什么
三道闸拆了,但记录的表全留着。
- 谁从哪个出口注册的,照记
- 哪些文件被传过,照记
只记不拦。
这一条很重要:拆掉「拦」,不等于放弃「知道」。 哪天真出现了大规模滥用,我们手上有数据可查,可以再决定要不要把某一道加回来——而且这次是有依据地加,不是凭想象加。
一个自己发现的坑
复盘的时候发现:那三张表里,有一张其实答不了它该答的问题。
记文件的那张表,主键是文件本身,重复的直接忽略——所以它只记住了第一个传这份文件的人。
也就是说,它回答不了「有几个账号传过同一份文件」这个问题。而那正是第三道闸如果要恢复所需要的证据。
一张自以为在记录、其实答不了问题的表,比没有更糟——因为你会以为自己有数据。
留下的守卫
三条闸拆掉之后,我们各留了一条测试盯着它别被加回来。
理由见拆掉的东西,要留一个「别加回来」的守卫:没有守卫的话,「顺手把闸加回来」不会被任何东西发现,而用户不会来告诉你「我本该有更多额度」。
一般化
加一道限制之前,把这四问过一遍:
- 它想拦的事,正常用户会不会无意中做出来?
- 真想钻空子的人,绕过它要花多大力气?
- 被误伤的人会不会来告诉你?
- 拆掉「拦」之后,你还能不能「知道」?
第 3 问最容易被跳过,而它决定了这道闸的代价是不是可见的。