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

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

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

本文實例為大家分享了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 @PathVariable使用時遇到的問題及解決

    SpringBoot @PathVariable使用時遇到的問題及解決

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

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

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

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

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

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

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

    springmvc視圖解析流程代碼實例

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

    Spring?boot?CommandLineRunner啟動任務(wù)傳參實例詳解

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

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

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

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

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

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

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

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

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

最新評論

平度市| 沭阳县| 清徐县| 十堰市| 呼图壁县| 泌阳县| 昌江| 威宁| 孟州市| 定边县| 马龙县| 荔浦县| 静海县| 长白| 东阳市| 邯郸市| 三原县| 眉山市| 岳西县| 馆陶县| 扶风县| 潍坊市| 东光县| 四川省| 睢宁县| 桑日县| 巩义市| 清远市| 凤凰县| 克什克腾旗| 九寨沟县| 东乡县| 奉贤区| 琼海市| 襄垣县| 津市市| 宽城| 富平县| 安平县| 临清市| 长宁县|