转自:https://www.cnblogs.com/dream-to-pku/p/7615139.html
前言
在平时的开发中我们都需要处理重复提交的问题,避免业务出错或者产生脏数据,虽然可以通过前端控制但这并不是可以完全避免,最好的方式还是前后端均进行控制,这样的话就可以更有效,尽可能全面的去减少错误的发生。
一、比如我们注册的时候需要发送验证码
如果用户频繁点击或者恶意攻击的话就会造成不断的请求对服务器产生很大的压力,为了避免这种情况我们需要做处理,传统的模式中是在数据库中记录手机号、验证码已经发送时间,再次请求的时候呢去数据库查询是否有该手机号记录,并校验是否超过间隔时间,如果超过则重新发送并更新时间,否组不予发送,这样有一个缺点就是如果同时又很多人在做相同的业务同时查询就会对数据库造成很大的压力。
根据此种情况我们可以使用Redis incrde 原子性递增,来解决这种高并发的秒杀或者分布式序列号生成等场景。鉴于本场景我们只用他来做计数实现间隔时间内只接收一次请求。
实现逻辑:在发送短信之后使用Redis的incr设置一个递增的KEY(根据自己的需要设定但是要保证每一个人的唯一),来判断该KEY的数值,如果等于1说明这是第一次请求,发送短信记录日志,并设置有效期,如果不等于的话说明是间隔时间内多次请求,就提示请求频繁,稍后重试。
1 String redisKey = "SMS_SEND_" + smsPhone; 2 long count = redisTemplate.opsForValue().increment(redisKey, 1); 3 if (count == 1) { 4 //设置有效期一分钟 5 redisTemplate.expire(redisKey, 60, TimeUnit.SECONDS); 6 } 7 if (count > 1) { 8 resultMap.put("retCode", "-1"); 9 resultMap.put("retMsg", "每分钟只能发送一次短信"); 10 outPrintJson(resultMap); 11 return; 12 } 13 /** 发送短信 */ 14 ...... 15 /** 记录发送日志 */ 16 ......