接口防止短时高并发、数据加锁
什么是短时高并发
高并发是指在极短单位时间内,有很多用户同时的访问同一 API 接口或者 Url 地址,造成极多个请求同时发起到服务器。
最近在安全检测短时高并发检测注册接口的时候,用户账号是Email,如果没做任何处理的话,通过短时高并发同一个邮箱会注册成功多次,这是错误的
我的解决办法是通过加锁
下面是代码实现:
工具类 RedissonUtil
@Component
public class RedissonUtil {
// 静态属性注入
private static RedissonClient redissonClient;
@Autowired
public void setRedisson(RedissonClient redissonclient) {
RedissonUtil.redissonClient = redissonclient;
}
// 获取分布式锁
public static RLock getLock(String lockName) {
return redissonClient.getLock(lockName);
}
// 尝试获取分布式锁,设置超时时间和过期时间
public static boolean tryLock(String lockName, long waitTime, long leaseTime, TimeUnit unit) throws InterruptedException {
RLock lock = redissonClient.getLock(lockName);
return lock.tryLock(waitTime, leaseTime, unit);
}
// 释放分布式锁
public static void unlock(String lockName) {
RLock lock = redissonClient.getLock(lockName);
if (lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
}
在你想要加锁的方法里面实现:
@Override
public AjaxResult userRegister(SysUserOkinawa sysUserOkinawa) {
String lockName = sysUserOkinawa.getEmail(); // 获取邮箱
try{
boolean isLocked = RedissonUtil.tryLock(lockName, 10, 10,TimeUnit.SECONDS); // 尝试获取分布式锁,设置超时时间和过期时间
if(!isLocked){
return AjaxResult.error(String.format("userRegister-getlockerror-{0}",lockName));
}
log.info("message:调用注册接口信息");
//验证邮箱是否存在
Integer count = sysUserOkinawaMapper.getByEmail(sysUserOkinawa.getEmail());
if(count != 0){
return AjaxResult.error("このメールアドレスは既に使われています。");
}
//业务处理保存数据库return AjaxResult.success("注册成功!");
}catch (Exception e){
log.info("message:调用注册接口失败");
log.info("message:注册失败{0}",e.toString());
return AjaxResult.error("注册失败"+e);
}finally {
RedissonUtil.unlock(lockName); // 最后一定要记得释放锁
}
}
上面两段代码,实现了简单通过上锁来避免结构被短时高并发攻击,造成邮箱注册多次情况出现
不是所有接口都需要,但是该有的要预防