91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java如何實現接口限流

發布時間:2021-11-25 11:09:27 來源:億速云 閱讀:353 作者:小新 欄目:開發技術

小編給大家分享一下Java如何實現接口限流,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!

RateLimiter

Google開源工具包Guava提供了限流工具類RateLimiter,基于令牌桶算法實現。

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;

/**
 * 令牌桶注解實現
 */
@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<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集合中是否有創建好的令牌桶
                    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; 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 "";
}

看完了這篇文章,相信你對“Java如何實現接口限流”有了一定的了解,如果想了解更多相關知識,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

怀远县| 赤水市| 延川县| 武清区| 林西县| 昆山市| 旬阳县| 平邑县| 文水县| 开平市| 广平县| 安龙县| 桓仁| 姜堰市| 淮阳县| 台湾省| 开鲁县| 大名县| 正蓝旗| 塘沽区| 时尚| 微博| 二手房| 美姑县| 巴南区| 龙南县| 邯郸县| 龙州县| 张家界市| 徐汇区| 读书| 安平县| 信宜市| 沧源| 肥西县| 永宁县| 厦门市| 万宁市| 东丰县| 双峰县| 定结县|