短信验证码系统怎么设计一次讲清发送频控、验证码校验、防刷与通道容灾大家好我是一名有 4 年工作经验的 Java 后端开发。短信验证码功能看起来简单但真正做成稳定系统里面其实有很多风控、频控、通道和可用性问题。这篇文章我想系统聊一聊短信验证码系统到底该怎么设计。个人主页文章目录短信验证码系统怎么设计一次讲清发送频控、验证码校验、防刷与通道容灾一、验证码系统最容易被低估的地方二、推荐的核心流程三、频控一定要做在哪几层3.1 单手机号频控3.2 单 IP 频控3.3 单设备频控3.4 单日总量限制四、验证码校验要注意什么4.1 TTL4.2 一次性使用4.3 错误次数限制五、通道容灾怎么做六、最容易踩的坑6.1 只做手机号限流不做 IP / 设备限制6.2 验证成功后不删除验证码6.3 短信发送失败也把验证码写成功6.4 没有发送日志七、面试中怎么回答八、总结九、结尾一、验证码系统最容易被低估的地方很多人第一次做验证码代码通常是生成 6 位数存 Redis调短信接口发送这当然能跑但很快就会遇到同一个手机号疯狂发验证码图形验证码都没做就被打爆短信通道偶发失败用户明明输对了却提示错误验证码被重复使用所以验证码系统真正要解决的是生成、发送、校验、防刷、通道可用性和风控一起设计。二、推荐的核心流程先做人机验证或基础风控生成验证码验证码写入 Redis并设置 TTL走短信通道发送校验时从 Redis 比对验证成功后立即失效这个流程里最关键的是频控一次性发送成功留痕三、频控一定要做在哪几层我更建议至少做这些限制3.1 单手机号频控例如60 秒内只能发一次3.2 单 IP 频控防止恶意机器刷接口。3.3 单设备频控更进一步防刷。3.4 单日总量限制避免通道成本和攻击风险。四、验证码校验要注意什么4.1 TTL通常验证码有效期不要太长比如5 分钟4.2 一次性使用校验成功后应立即删除。4.3 错误次数限制比如连续输错 5 次锁定一段时间五、通道容灾怎么做短信通道并不总是稳定的。所以如果短信量大建议主通道备通道失败切换同时要有发送结果日志通道成功率监控六、最容易踩的坑6.1 只做手机号限流不做 IP / 设备限制很容易被批量刷。6.2 验证成功后不删除验证码这会让验证码变成可重复使用。6.3 短信发送失败也把验证码写成功后面会出现用户拿不到码但系统以为已经发成功。6.4 没有发送日志排查投诉会很困难。七、面试中怎么回答如果面试官问你短信验证码系统一般怎么设计你可以这样回答第一我会把验证码系统拆成生成、发送、校验和风控四层不会只把它当成一个简单的 Redis 短信接口调用。第二风控和频控非常关键至少会限制单手机号、单 IP、单设备的发送频率并对单日发送量做控制避免被恶意刷接口。第三验证码在 Redis 里通常会设置较短 TTL校验成功后立即删除保证一次性使用同时短信通道侧最好有发送日志和通道容灾能力方便排查和切换。八、总结验证码系统真正难的不是生成 6 位数而是如何把发送校验频控风控通道稳定性真正一起考虑进去。如果只记一句结论我觉得可以记住这句验证码系统最稳的做法不是只把验证码存进 Redis而是“频控、一次性、发送留痕、通道容灾”一起设计。九、结尾如果你觉得这篇文章对你有帮助欢迎点赞、收藏、关注。后面我会继续整理一些更偏实战的 Java 后端和基础设施设计文章尽量少写空泛概念多写真实项目里会踩到的坑。