最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java實(shí)現(xiàn)接口限流方案

 更新時(shí)間:2021年11月25日 15:31:54   作者:Lamantin  
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)接口限流方案,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

本文實(shí)例為大家分享了Java實(shí)現(xiàn)接口限流方案的具體代碼,供大家參考,具體內(nèi)容如下

RateLimiter

Google開源工具包Guava提供了限流工具類RateLimiter,基于令牌桶算法實(shí)現(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;

/**
 * 令牌桶注解實(shí)現(xiàn)
 */
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestLimiter {
    /**
     * 每秒創(chuàng)建令牌個(gè)數(shù),默認(rèn):10
     */
    double QPS() default 10D;

    /**
     * 獲取令牌等待超時(shí)時(shí)間 默認(rèn):500
     */
    long timeout() default 500;

    /**
     * 超時(shí)時(shí)間單位 默認(rèn):毫秒
     */
    TimeUnit timeunit() default TimeUnit.MILLISECONDS;

    /**
     * 無法獲取令牌返回提示信息
     */
    String msg() default "請(qǐng)稍后再試!";
}

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", "玩命加載中,請(qǐng)稍后再試");
        try {
            if (handler instanceof HandlerMethod) {
                HandlerMethod handlerMethod = (HandlerMethod) handler;
                RequestLimiter rateLimit = handlerMethod.getMethodAnnotation(RequestLimiter.class);
                //判斷是否有注解
                if (rateLimit != null) {
                    // 獲取請(qǐng)求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("請(qǐng)求被限流,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.注冊(cè)攔截器

@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {

     /**
      * 請(qǐng)求限流攔截器
      */
     @Autowired
     protected RequestLimitingInterceptor requestLimitingInterceptor;

     @Override
     public void addInterceptors(InterceptorRegistry registry) {
         // 請(qǐng)求限流
         registry.addInterceptor(requestLimitingInterceptor).addPathPatterns("/**");
     }

}

5.在接口上配置注解

@RequestLimiter(QPS = 5D, timeout = 200, timeunit = TimeUnit.MILLISECONDS,msg = "玩命加載中,請(qǐng)稍后再試")
@GetMapping("/test")
@ResponseBody
public String test(){
      return "";
}

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • SpringBoot @PathVariable使用時(shí)遇到的問題及解決

    SpringBoot @PathVariable使用時(shí)遇到的問題及解決

    這篇文章主要介紹了SpringBoot @PathVariable使用時(shí)遇到的問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Spring動(dòng)態(tài)多數(shù)據(jù)源配置實(shí)例Demo

    Spring動(dòng)態(tài)多數(shù)據(jù)源配置實(shí)例Demo

    本篇文章主要介紹了Spring動(dòng)態(tài)多數(shù)據(jù)源配置實(shí)例Demo,具有一定的參考價(jià)值,有興趣的可以了解一下。
    2017-01-01
  • Java ThreadLocal的使用場(chǎng)景總結(jié)

    Java ThreadLocal的使用場(chǎng)景總結(jié)

    ThreadLocal原本設(shè)計(jì)是為了解決并發(fā)時(shí),線程共享變量的問題,但由于過度設(shè)計(jì),從而導(dǎo)致它的理解難度大和使用成本高等問題。即便如此,ThreadLocal依舊有適合自己的使用場(chǎng)景,比如本文要介紹了這兩種使用場(chǎng)景,除了ThreadLocal之外,還真沒有合適的替代方案。
    2021-05-05
  • Java之Spring注解開發(fā)案例詳解

    Java之Spring注解開發(fā)案例詳解

    這篇文章主要介紹了Java之Spring注解開發(fā)案例詳解,本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • springmvc視圖解析流程代碼實(shí)例

    springmvc視圖解析流程代碼實(shí)例

    這篇文章主要介紹了springmvc視圖解析流程代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-01-01
  • Spring?boot?CommandLineRunner啟動(dòng)任務(wù)傳參實(shí)例詳解

    Spring?boot?CommandLineRunner啟動(dòng)任務(wù)傳參實(shí)例詳解

    在使用SpringBoot構(gòu)建項(xiàng)目時(shí),我們通常有一些預(yù)先數(shù)據(jù)的加載,下面這篇文章主要給大家介紹了關(guān)于Spring?boot?CommandLineRunner啟動(dòng)任務(wù)傳參的相關(guān)資料,需要的朋友可以參考下
    2022-06-06
  • SSH框架網(wǎng)上商城項(xiàng)目第8戰(zhàn)之查詢和刪除商品類別功能實(shí)現(xiàn)

    SSH框架網(wǎng)上商城項(xiàng)目第8戰(zhàn)之查詢和刪除商品類別功能實(shí)現(xiàn)

    SSH框架網(wǎng)上商城項(xiàng)目第8戰(zhàn)之查詢和刪除商品類別功能實(shí)現(xiàn),為項(xiàng)目增加功能,添加、更新、刪除和查詢操作,感興趣的小伙伴們可以參考一下
    2016-05-05
  • mybatis-plus?分頁類型轉(zhuǎn)換工具類

    mybatis-plus?分頁類型轉(zhuǎn)換工具類

    用mybatis-plus?的分頁對(duì)象的時(shí)候,因?yàn)橛胢ybatis-puls?查詢出來的分頁對(duì)象的records里的泛型是實(shí)體,有時(shí)候需要將實(shí)體轉(zhuǎn)換為前端展示的對(duì)象,所有寫了一個(gè)分頁數(shù)據(jù)的類型轉(zhuǎn)換工具,解決這個(gè)問題,對(duì)mybatis-plus?分頁工具類相關(guān)知識(shí)感興趣的朋友一起看看吧
    2022-03-03
  • SpringBoot配置線程池的實(shí)現(xiàn)示例

    SpringBoot配置線程池的實(shí)現(xiàn)示例

    本文主要介紹了SpringBoot配置線程池的實(shí)現(xiàn)示例,主要包括在Spring Boot中創(chuàng)建和配置線程池,包括設(shè)置線程池的大小、隊(duì)列容量、線程名稱等參數(shù),感興趣的可以了解一下
    2023-09-09
  • Java 蒙特卡洛算法求圓周率近似值實(shí)例詳解

    Java 蒙特卡洛算法求圓周率近似值實(shí)例詳解

    這篇文章主要介紹了蒙特卡洛算法的起源,特點(diǎn),以及Java編程中利用蒙特卡洛算法計(jì)算圓周率近似值的實(shí)例,需要的朋友可以參考下
    2017-09-09

最新評(píng)論

阳东县| 香格里拉县| 酒泉市| 工布江达县| 南开区| 波密县| 关岭| 滨州市| 积石山| 永城市| 炎陵县| 青川县| 临江市| 兴和县| 沙坪坝区| 丁青县| 平利县| 青川县| 堆龙德庆县| 商城县| 独山县| 吉安县| 大名县| 西平县| 安乡县| 资源县| 扶绥县| 沈丘县| 濮阳市| 黄石市| 招远市| 林甸县| 藁城市| 汾阳市| 延庆县| 泗水县| 上虞市| 金寨县| 广宁县| 麻阳| 舞钢市|