Java实现接口限流方案

网友投稿 1223 2022-09-13


Java实现接口限流方案

本文实例为大家分享了java实现接口限流方案的具体代码,供大家参考,具体内容如下

RateLimiter

Google开源工具包Guava提供了限流工具类RateLimiter,基于令牌桶算法实现。

1.maven依赖:

com.google.guava

guava

27.1-jre

2.自定义注解

import java.lang.annotation.*;

import java.util.concurrent.TimeUnit;

/**

* 令牌桶注解实现

*/

@Target({ElementType.METHOD})

@Retention(RetentionPolicy.RUNTIME)

@Documented

public @interface RequestLimiter {

/**

* 每秒创建令牌个数,默认:10

*/

double QPS() default 10D;

/**

* 获取令牌等待超时时间 默认:500

*/

long timeout() default 500;

/**

* 超时时间单位 默认:毫秒

*/

TimeUnit timeunit() default TimeUnit.MILLISECONDS;

/**

* 无法获取令牌返回提示信息

*/

String msg() default "请稍后再试!";

}

3.拦截器

import com.alibaba.fastjson.JSON;

import com.alibaba.fastjson.JSONObject;

import com.google.common.util.concurrent.RateLimiter;

import com.tiam.panshi.cloud.appback.annotation.RequestLimiter;

import lombok.extern.slf4j.Slf4j;

import org.springframework.stereotype.Component;

import org.springframework.web.method.HandlerMethod;

import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import java.io.PrintWriter;

import java.util.Map;

import java.util.concurrent.ConcurrentHashMap;

@Component

@Slf4j

public class RequestLimitingInterceptor implements HandlerInterceptor {

private final Map rateLimiterMap = new ConcurrentHashMap<>();

@Override

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {

//这里可以抽出去定义返回信息

JSONObject jsonObject = new JSONObject();

jsonObject.put("10001", "玩命加载中,请稍后再试");

try {

if (handler instanceof HandlerMethod) {

HandlerMethod handlerMethod = (HandlerMethod) handler;

RequestLimiter rateLimit = handlerMethod.getMethodAnnotation(RequestLimiter.class);

//判断是否有注解

if (rateLimit != null) {

// 获取请http://求url

String url = request.getRequestURI();

RateLimiter rateLimiter;

// 判断map集合中是否有创建好的令牌桶

if (!rateLimiterMap.containsKey(url)) {

// 创建令牌桶,以n r/s往桶中放入令牌

rateLimiter = RateLimiter.create(rateLimit.QPS());

rateLimiterMap.put(url, rateLimiter);

}

rateLimiter = rateLimiterMap.get(url);

// 获取令牌

boolean acquire = rateLimiter.tryAcquire(rateLimit.timeout(), rateLimit.timeunit());

if (acquire) {

//获取令牌成功

return true;

} else {

log.warn("请求被限流,url:{}", request.getServletPath());

makeResult(response, renderJson(jsonObject));

return false;

}

}

}

return true;

} catch (Exception var6) {

var6.printStackTrace();

makeResult(response, renderJson(jsonObject));

return false;

}

}

private void makeResult(HttpServletResponse response, JSONObject jo) {

response.setContentType("application/json; chttp://harset=utf-8");

response.setCharacterEncoding("UTF-8");

try (PrintWriter out = response.getWriter()) {

out.append(jo.toJSONString());

} catch (Exception e) {

e.printStackTrace();

}

}

private JSONObject renderJson(Object o) {

return JSONObject.parseObject(JSON.toJSONString(o));

}

4.注册拦截器

@Configuration

public class WebMvcConfig extends WebMvcConfigurationSupport {

/**

* 请求限流拦截器

*/

@Autowired

protected RequestLimitingInterceptor requestLimitingInterceptor;

@Override

public void addInterceptors(InterceptorRegistry registry) {

// 请求限流

registry.addInterceptor(requestLimitingInterceptor).addPathPatterns("/**");

}

}

5.在接口上配置注解

@RequestLimiter(QPS = 5D, timeout = 200, timeunit = TimeUnit.MILLISECONDS,msg = "玩命加载中,请稍后再试")

@GetMapping("/test")

@ResponseBody

public String test(){

return "";

}


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:【OPNsense】广东电信拨号用户通过OPNsense获取原生IPV6地址
下一篇:Receive a message from AAA of cutting user on华为设备(receive是什么意思)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~