SpringMVC 限流

在使用SpringBoot做接口訪問如何做接口的限流,這里我們可以使用google的Guava包來實現(xiàn),當然我們也可以自己實現(xiàn)限流,Guava中的限流是久經(jīng)考驗的我們沒必需重新再去寫一個,如果想了解限流原理的同學可以自己查閱一下相關的資料,本文不作過來說明噢。

使用說明

在項目中引入Guava相關包

http://mvnrepository.com/artifact/com.google.guava/guava/21.0

maven項目

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>21.0</version>
</dependency>

gradle項目

compile group: 'com.google.guava', name: 'guava', version: '21.0'

寫一個SpringMVC的攔截器
SmoothBurstyInterceptor.java

import com.google.common.util.concurrent.RateLimiter;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.concurrent.TimeUnit;

public class SmoothBurstyInterceptor extends HandlerInterceptorAdapter {

    public enum LimitType {
        DROP,//丟棄
        WAIT //等待
    }

    /**
     * 限流器
     */
    private RateLimiter limiter;
    /**
     * 限流方式
     */
    private LimitType limitType = LimitType.DROP;

    public SmoothBurstyInterceptor() {
        this.limiter = RateLimiter.create(10);
    }

    /**
     * @param tps       限流量 (每秒處理量)
     * @param limitType 限流類型:等待/丟棄(達到限流量)
     */
    public SmoothBurstyInterceptor(int tps, SmoothBurstyInterceptor.LimitType limitType) {
        this.limiter = RateLimiter.create(tps);
        this.limitType = limitType;
    }
    /**
     * @param permitsPerSecond  每秒新增的令牌數(shù)
     * @param limitType 限流類型:等待/丟棄(達到限流量)
     */
    public SmoothBurstyInterceptor(double permitsPerSecond, SmoothBurstyInterceptor.LimitType limitType) {
        this.limiter = RateLimiter.create(permitsPerSecond, 1000, TimeUnit.MILLISECONDS);
        this.limitType = limitType;
    }


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (limitType.equals(LimitType.DROP)) {
            if (limiter.tryAcquire()) {
                return super.preHandle(request, response, handler);
            }
        } else {
            limiter.acquire();
            return super.preHandle(request, response, handler);
        }
        throw new Exception("網(wǎng)絡異常!");//達到限流后,往頁面提示的錯誤信息。
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        super.afterCompletion(request, response, handler, ex);
    }

    public RateLimiter getLimiter() {
        return limiter;
    }

    public void setLimiter(RateLimiter limiter) {
        this.limiter = limiter;
    }
}

SpringMVC攔截配置
WebConfig.java

@Component
public class WebConfig extends WebMvcConfigurerAdapter {
    
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 多個攔截器組成一個攔截器鏈
        registry.addInterceptor(new SmoothBurstyInterceptor(100, SmoothBurstyInterceptor.LimitType.DROP)).addPathPatterns("/**");
        //限流可配置為SmoothBurstyInterceptor.LimitType.DROP丟棄請求或者SmoothBurstyInterceptor.LimitType.WAIT等待,100為每秒的速率
        super.addInterceptors(registry);
    }

}

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容