项目中遇到一个很有趣的问题,对文件上传做流控
具体需求:
每个10分钟内只能上传20个文件,超过20个则提示用户30分钟后再试。
不超过20个则过10分钟还能上传20个。
方案一:这里可以用数据库,将用户上传的次数存到数据库。。。具体怎么操作,略
方案二:用redis,当用户上传第一张时设置value = 1,之后上传则自增1
private static final String UPLOAD_FILE_COUNT = "uploadFileCount@";
@Autowired
@Qualifier("redisClient")
private StringRedisTemplate redisTemplate;
@GetMapping(value = "/setRedis", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public HashMap<String, Object> setRedis() {
String counting = redisTemplate.opsForValue().get(UPLOAD_FILE_COUNT + "user");
Long leftTime = redisTemplate.getExpire(UPLOAD_FILE_COUNT + "user");
if (ObjectUtils.isNotEmpty(leftTime)) {
if (StringUtils.isNotEmpty(counting) && Long.parseLong(counting) >= 20) {
// leftTime过期时间如果大于二十分钟 则为十分钟内传了20次
if (leftTime > 0) {
if ("20".equals(counting)) {
redisTemplate.opsForValue().set(UPLOAD_FILE_COUNT + "user", "21", 30, TimeUnit.MINUTES);
}
HashMap<String, Object> objectObjectHashMap = new HashMap<>();
objectObjectHashMap.put("报错语句", "频繁操作,请与30分钟后再操作");
objectObjectHashMap.put("count的数量", redisTemplate.opsForValue().get(UPLOAD_FILE_COUNT + "user"));
objectObjectHashMap.put("count的过期时间", redisTemplate.getExpire(UPLOAD_FILE_COUNT + "user"));
return objectObjectHashMap;
}
}
}
if (Objects.equals(redisTemplate.hasKey(UPLOAD_FILE_COUNT + "user"), Boolean.TRUE)) {
//如果存在则自增,不存在则添加该redisKey
redisTemplate.opsForValue().increment(UPLOAD_FILE_COUNT + "user");
} else {
redisTemplate.opsForValue().set(UPLOAD_FILE_COUNT + "user", COUNT_INIT, ALLOW_TIME, TimeUnit.MINUTES);
}
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("count的次数", redisTemplate.opsForValue().get(UPLOAD_FILE_COUNT + "user"));
hashMap.put("count的过期时间", redisTemplate.getExpire(UPLOAD_FILE_COUNT + "user"));
hashMap.put("leftTime", leftTime);
return hashMap;
}
注意:
1.10分钟后可以再次上传20次,设置redis过期时间为10
2.当在10分钟之内,次数大于20次则设置value为21,过期时间为30
3.如果value为20,则设置value为21,这样就不会重复走判断value = 20的逻辑了,不会使得redis重复设置
4.isExist一定是有值的,判断是否存在,不存在则设置,存在则自增
当然这只是一个小demo写得有点捞,具体用到代码上还需要把那些常数提出来。。。