private final AtomicInteger tick = new AtomicInteger();
@ResponseBody
@RequestMapping(value = "/url", method = { RequestMethod.POST })
public String geturl(参数) {
try {
if (waitInLine()) {
return 告诉用户现在系统处理能力不足,稍候再试;
}
// 判断是否重复点击
if (isFrequently(memberId)) {
return 告诉用户不要重复点击按钮,系统正在处理上一次的请求;
}
//业务代码
return 业务代码后的返回结果;
}
} catch (Exception e) {
return CommonConstant.gson.toJson(packetResult);
} finally {
//一定要写finally
tick.decrementAndGet();
}
}
/**
* 判断是否超出处理范围
*
* @return
*/
private boolean waitInLine() {
return tick.incrementAndGet() > 1000;//表示系统最多同时处理1000个请求
}
/**
* 判断是否提交过频繁
*
* @param memberId
* 会员id
* @return
*/
public boolean isFrequently(String memberId) {
ShardedJedis jedis = null;
try {
jedis = RedisFactory.getJedis();
if (CommonUtils.isNull(jedis.get(memberId))) {
jedis.set(memberId, "");
jedis.expire(memberId, 1);//1秒后标记就消失
} else {
return true;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
RedisFactory.returnResource(jedis);//回收连接
}
return false;
}
2021-6-22 补充:上边代码是萌新时期抄的,但是代码是有并发问题的。
限制流量推荐hystrix 以及guava的RateLimit
防止重复点击的代码,isFrequently不是原子性的,因为当时是使用的旧版本的jedis,新版本的jedis代码是有原子性的set方法的。
@Override
public String set(String key, String value, String nxxx, String expx, long time) {
Jedis j = getShard(key);
return j.set(key, value, nxxx, expx, time);
}
本文介绍了一种基于AtomicInteger的简单限流方法,并通过Redis实现防重复点击功能。但指出这种方法存在并发问题,建议使用Hystrix或Guava RateLimiter等更稳定的技术进行限流。
1万+

被折叠的 条评论
为什么被折叠?



