啰嗦几句
打铁还需自身硬,如今AI横行,对新开发肯定很不友好,不利于新开发的成长,对老开发来说,肯定是得力助手,但是秉承学会的都是自己的,我们还是要活到老,学到老,话不多说,本篇我们就来一起研究防重提交怎么做。
正片开始
这里直接推荐使用Guardian,不需要自己再造轮子,用现成的不香吗,这是一个轻量级的 Spring Boot Starter,专门用于解决接口防护问题(防重、限流、幂等),优点呢,零代码侵入,配置简单,支持 Redis 和本地缓存,支持注解和 YAML 批量配置。
简单举例:

- 引入依赖
io.github.biggg-guardian guardian-repeat-submit-spring-boot-starter 1.5.0 - 添加注解
@PostMapping("/submit")@RepeatSubmit(interval = 10, message = "订单正在处理,请勿重复提交")public Result submitOrder(@RequestBody OrderDTO order) { return orderService.submit(order);}注:默认 10 秒内,同一用户、同一接口、同一参数会被拦截。- YAML 批量配置
guardian: repeat-submit: storage: redis # 使用 Redis 存储(集群环境推荐) key-encrypt: md5 urls: - pattern: /api/order/** # 匹配该路径下的所有接口 interval: 10 key-scope: user # 按用户维度防重 message: "系统繁忙,请稍后再试" - pattern: /api/sms/** interval: 60 key-scope: ip # 短信接口通常按 IP 防重还可以配合数据库唯一约束兜底,在数据库表中建立唯一索引(Unique Key)。例如,在订单表中,将 user_id + order_token 或者 request_id 设为唯一索引。
除了用Guardian,还有比如实现:
- 自定义注解 + AOP + Redis
- Token 机制(前后端协同)
这里不做过多说明,感兴趣可以自行查阅学习哈。
疑问
- 前端防重如何做?
表单提交、关键操作按钮,按钮禁用,前端只要简单这样处理就行了,主要在后端处理防重。
- Guardian是不是只适合单机环境?
并不是, Guardian完全支持分布式环境,并非仅限于单机使用。
配置示例
guardian: repeat-submit: storage: redis # 核心配置:指定使用 Redis 存储,即可支持分布式 key-encrypt: md5 urls: - pattern: /api/order/** interval: 10 message: "请勿重复提交"- 为什么我更推荐 Guardian?
1. 它是“六合一”的防护体系,不仅仅是防重:接口限流,接口幂等,防刷/防重放,监控能力
2. 配置极其灵活(YAML vs 注解)
3. 避免了“重复造轮子”的坑:Key 冲突(不同业务用了相同的 Key 前缀);死锁(业务报错后忘记释放 Redis 锁(虽然 Guardian 也有过期时间,但它处理得更完善));序列化问题(Redis 存储 Value 时的序列化异常)
- 之前分布式限流不是推荐用Spring Cloud Gateway + Redis吗,现在只要用Guardian Starter是吗?
并不是说“只用 Guardian”就够了,而是看你的限流需求是在“网关层”还是“业务层”。这两者不是替代关系,而是互补关系。所以,Guardian 并没有取代网关限流,而是填补了网关无法处理的“业务级防护”空白。
- Redisson和Guardian都能分布式业务层限流,推荐用哪个?
简单来说,Redisson 是底层的“发动机”,而 Guardian Starter 是已经组装好的“整车”,优先使用 Guardian,除非你有 Redisson 才能满足的特殊需求。
记忆点
防重
聊天吹水
其实AI越来越智能,就经常看到有人提问AI什么时候能取代程序员啊,什么某某大厂疯狂裁员啊之类的,博主也开始焦虑了,作为一名Java开发,要是以后真的失业了,能干啥,摆地摊吗,开店吗,还是转行,感觉各行各位都会受AI影响,而且现在工作怎么说呢,懂的都懂,经常就看到一些同行说难找,又更加焦虑啊,同行们,你们怎么看?欢迎留言~