同一个号码一分钟内收到六条短信,风控后台看每次提交的值都不一样,一个带空格一个带 +86,还有一个前后各加了一个零宽字符。日志里能对上时间点,这种反而好排。
发送限制按原始字符串做键,号码没做归一化,空格、国家码、全角数字都能生成新键,每次提交都被当成第一次请求,次数限制形同虚设。这一点先确认清楚,后面就不用反复试。
phone = re.sub('[^0-9]', '', raw)[-11:]
key = 'sms:%s' % phone
redis.set(key, code, ex=60, nx=True)
这次卡住的地方就在「短信验证码防刷」这一环,单独把它拎出来验证,别和其他改动混在同一次发布里。线上出问题先对时间点,跟发布、备份、任务执行的时刻排一排,能省掉一半功夫。
处理上按这个顺序:入库前去掉空格和符号,统一成纯数字加国家码;发送限制同时按手机号和来源 IP 两个维度来计数;发送记录落库,重复号码直接复用未过期的验证码。
结果对不对很好判断,同一号码换写法提交只会发一条短信,第二次直接提示稍后再试。
