记一个设置接口限定时间内访问次数的问题
2020-03-25 本文已影响0人
凉风拂面秋挽月
问题
前端需求是在一定时间内,访问一个服务器的一个接口不能超过规定次数。按照业务划分,这应该是前端解决的问题,抛到后端来解决实在是。。
分析需求
查找了一下网上限制ip访问次数的方案,基本都是aop做切面解决的。通过自定义接口注解在指定方法上;切面为controller&&limit(自定义接口)。
实现逻辑也很简单,首次访问该接口时,将次数count缓存到redis中,key为接口名。然后定时清空。返回之前先从redis中取数据判断,如果count超过指定值,直接返回error。如果没超过count++后,则该正常处理返回。
小demo
自己模拟访问场景,写个小demo。
访问指定方法20次,在规定时间内超过访问次数则返回error。未超过则返回success。超时将刷新count。
import java.util.HashMap;
/**
* 解决同一方法的多次访问
* @author xuxiao
*
*/
public class test {
private static final int LIMIT = 5; //限制访问次数
private static final int FRESH_TIME =10*1000//限定10秒内,允许访问5次,10秒后刷新。
//hashmap模拟redis
private HashMap<String,Integer> hashmap = new HashMap<>();
//Thread模拟Timer
private Thread thread = new Thread();
{
hashmap.put("xuxiao", 0);
}
public String mywork() {
int count = hashmap.get("xuxiao");
if(count>LIMIT) {
return "error";
}
if(!thread.isAlive()) {
thread = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(FRESH_TIME);//设定超时
hashmap.put("xuxiao", 0);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
thread.start();
}
hashmap.put("xuxiao",++count);
return "success";
}
public static void main(String[] args) throws InterruptedException {
test t = new test();
//模拟前端每隔1秒访问一次接口
for(int i=0;i<20;i++) {
System.out.println(t.mywork());
Thread.sleep(1000);
}
}
}
运行结果:
success
success
success
success
success
success
error
error
error
error
success
success
success
success
success
success
error
error
error
error