Java實現(xiàn)接口限流方案
本文實例為大家分享了Java實現(xiàn)接口限流方案的具體代碼,供大家參考,具體內(nèi)容如下
RateLimiter
Google開源工具包Guava提供了限流工具類RateLimiter,基于令牌桶算法實現(xiàn)。
1.maven依賴:
<dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>27.1-jre</version> </dependency>
2.自定義注解
import java.lang.annotation.*; import java.util.concurrent.TimeUnit; /** * 令牌桶注解實現(xiàn) */ @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface RequestLimiter { /** * 每秒創(chuàng)建令牌個數(shù),默認(rèn):10 */ double QPS() default 10D; /** * 獲取令牌等待超時時間 默認(rèn):500 */ long timeout() default 500; /** * 超時時間單位 默認(rèn):毫秒 */ 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<String, RateLimiter> 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) { // 獲取請求url String url = request.getRequestURI(); RateLimiter rateLimiter; // 判斷map集合中是否有創(chuàng)建好的令牌桶 if (!rateLimiterMap.containsKey(url)) { // 創(chuàng)建令牌桶,以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; charset=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 ""; }
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot實現(xiàn)阿里云短信接口對接的示例代碼
這篇文章主要介紹了SpringBoot實現(xiàn)阿里云短信接口對接的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09如何使用IDEA開發(fā)Spark SQL程序(一文搞懂)
Spark SQL 是一個用來處理結(jié)構(gòu)化數(shù)據(jù)的spark組件。它提供了一個叫做DataFrames的可編程抽象數(shù)據(jù)模型,并且可被視為一個分布式的SQL查詢引擎。這篇文章主要介紹了如何使用IDEA開發(fā)Spark SQL程序(一文搞懂),需要的朋友可以參考下2021-08-08Dwr3.0純注解(純Java Code配置)配置與應(yīng)用淺析三之后端反向調(diào)用前端
Dwr是為人所熟知的前端框架,其異步推送功能是為人所津津樂道的,下來主要研究一下它的這個功能是怎么應(yīng)用的;2016-04-04Spring Cloud Data Flow初體驗以Local模式運行
這篇文章主要介紹了Spring Cloud Data Flow初體驗以Local模式運行,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-08-08SpringBoot+Mybatis-plus+shardingsphere實現(xiàn)分庫分表的方案
實現(xiàn)億級數(shù)據(jù)量分庫分表的項目是一個挑戰(zhàn)性很高的任務(wù),下面是一個基于Spring Boot的簡單實現(xiàn)方案,感興趣的朋友一起看看吧2024-03-03postman中實現(xiàn)傳遞@RequestBody參數(shù)
這篇文章主要介紹了postman中實現(xiàn)傳遞@RequestBody參數(shù),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-10-10