先理一下用户重复提交出现的问题
- 假设有一个用户想要上传一件商品但是因为网速慢用户疯狂点击上传按钮导致发出多个请求到达了服务端,然后服务端把这些请求都送达到了关系数据库,最后可能重复上传商品,也可能造成关系数据库压力过大。
解决办法
1、单机环境
使用一个本地的缓存池类似KV结构的数据结构(这个推荐google开源的guava),当一个用户在一个接口发送请求时候,生成一个关于这个用户和这个接口的key,存入本地缓存,当这个接口请求完了删除这个key,如果这个key存在就把用户的请求直接return。
2、集群环境
使用redis来记录用户请求,这里推荐直接使用开源的redisson分布式锁来解决,每当有一个用户请求一个接口,就锁住,但是只是这个用户请求的时候才会被锁,其他用户就重新生成锁,然后方法执行完了再释放。
建议
笔者建议给锁和缓存都设置自动删除时间,以防在用户访问这个接口的时候出现宕机然后key依然存在在redis,当用户再次访问这个接口的时候方法还是把这个用户锁住。
笔者自己的实现
https://github.com/guoyitao/ReSubmit