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

SpringBoot接口訪問頻率限制的實(shí)現(xiàn)方式

 更新時(shí)間:2024年07月23日 10:05:53   作者:一休哥助手  
接口訪問頻率限制是通過在一定時(shí)間內(nèi)限制用戶對(duì)接口的訪問次數(shù)來實(shí)現(xiàn)的,在Spring Boot中,我們可以通過多種方式來實(shí)現(xiàn)接口的限流,如使用過濾器、攔截器或者借助第三方庫,本文給大家講解的非常詳細(xì),需要的朋友可以參考下

概述

接口訪問頻率限制是通過在一定時(shí)間內(nèi)限制用戶對(duì)接口的訪問次數(shù)來實(shí)現(xiàn)的。常見的限流算法包括令牌桶算法(Token Bucket)、漏桶算法(Leaky Bucket)、固定窗口計(jì)數(shù)器(Fixed Window Counter)和滑動(dòng)窗口計(jì)數(shù)器(Sliding Window Counter)等。在Spring Boot中,我們可以通過多種方式來實(shí)現(xiàn)接口的限流,如使用過濾器、攔截器或者借助第三方庫。

為什么需要接口訪問頻率限制

  1. 防止惡意攻擊:通過限制接口的訪問頻率,可以有效防止惡意用戶或機(jī)器人頻繁訪問接口,導(dǎo)致系統(tǒng)資源耗盡。
  2. 提升系統(tǒng)穩(wěn)定性:在高并發(fā)場(chǎng)景下,限流可以有效保護(hù)后端服務(wù),避免因流量過大而導(dǎo)致系統(tǒng)崩潰。
  3. 提升用戶體驗(yàn):合理的限流可以保障所有用戶都能獲得較好的服務(wù)質(zhì)量,避免個(gè)別用戶過度使用資源。

常見的實(shí)現(xiàn)方式

基于過濾器的實(shí)現(xiàn)

過濾器是Java Web應(yīng)用中常用的一種組件,它可以在請(qǐng)求到達(dá)Servlet之前對(duì)請(qǐng)求進(jìn)行預(yù)處理。通過在過濾器中實(shí)現(xiàn)限流邏輯,可以對(duì)所有的HTTP請(qǐng)求進(jìn)行統(tǒng)一的限流控制。

基于攔截器的實(shí)現(xiàn)

攔截器是Spring框架提供的一種處理器,可以在請(qǐng)求處理之前和之后進(jìn)行相關(guān)操作。相比于過濾器,攔截器可以更加細(xì)粒度地控制請(qǐng)求,適用于需要針對(duì)某些特定接口進(jìn)行限流的場(chǎng)景。

基于第三方庫Bucket4j的實(shí)現(xiàn)

Bucket4j是一個(gè)Java實(shí)現(xiàn)的高性能限流庫,它支持多種限流算法,如令牌桶算法。通過使用Bucket4j,可以輕松地在Spring Boot應(yīng)用中實(shí)現(xiàn)復(fù)雜的限流邏輯,并且它還提供了豐富的配置選項(xiàng)和統(tǒng)計(jì)功能。

實(shí)際代碼示例

基于過濾器實(shí)現(xiàn)Rate Limiting

首先,我們需要?jiǎng)?chuàng)建一個(gè)自定義的過濾器類,并在其中實(shí)現(xiàn)限流邏輯。以下是一個(gè)示例代碼:

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;

public class RateLimitingFilter implements Filter {
    private final ConcurrentMap<String, Long> requestCounts = new ConcurrentHashMap<>();
    private static final long ALLOWED_REQUESTS_PER_MINUTE = 60;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 初始化過濾器
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;

        String clientIp = httpRequest.getRemoteAddr();
        long currentTimeMillis = System.currentTimeMillis();
        requestCounts.putIfAbsent(clientIp, currentTimeMillis);

        long lastRequestTime = requestCounts.get(clientIp);
        if (TimeUnit.MILLISECONDS.toMinutes(currentTimeMillis - lastRequestTime) < 1) {
            long requestCount = requestCounts.values().stream().filter(time -> TimeUnit.MILLISECONDS.toMinutes(currentTimeMillis - time) < 1).count();
            if (requestCount > ALLOWED_REQUESTS_PER_MINUTE) {
                httpResponse.setStatus(HttpServletResponse.SC_TOO_MANY_REQUESTS);
                httpResponse.getWriter().write("Too many requests");
                return;
            }
        }
        
        requestCounts.put(clientIp, currentTimeMillis);
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        // 銷毀過濾器
    }
}

然后,在Spring Boot應(yīng)用的配置類中注冊(cè)這個(gè)過濾器:

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FilterConfig {

    @Bean
    public FilterRegistrationBean<RateLimitingFilter> loggingFilter(){
        FilterRegistrationBean<RateLimitingFilter> registrationBean = new FilterRegistrationBean<>();
        
        registrationBean.setFilter(new RateLimitingFilter());
        registrationBean.addUrlPatterns("/api/*");
        
        return registrationBean;
    }
}

基于攔截器實(shí)現(xiàn)Rate Limiting

首先,我們需要?jiǎng)?chuàng)建一個(gè)自定義的攔截器類,并在其中實(shí)現(xiàn)限流邏輯。以下是一個(gè)示例代碼:

import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;

public class RateLimitingInterceptor implements HandlerInterceptor {
    private final ConcurrentMap<String, Long> requestCounts = new ConcurrentHashMap<>();
    private static final long ALLOWED_REQUESTS_PER_MINUTE = 60;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String clientIp = request.getRemoteAddr();
        long currentTimeMillis = System.currentTimeMillis();
        requestCounts.putIfAbsent(clientIp, currentTimeMillis);

        long lastRequestTime = requestCounts.get(clientIp);
        if (TimeUnit.MILLISECONDS.toMinutes(currentTimeMillis - lastRequestTime) < 1) {
            long requestCount = requestCounts.values().stream().filter(time -> TimeUnit.MILLISECONDS.toMinutes(currentTimeMillis - time) < 1).count();
            if (requestCount > ALLOWED_REQUESTS_PER_MINUTE) {
                response.setStatus(HttpServletResponse.SC_TOO_MANY_REQUESTS);
                response.getWriter().write("Too many requests");
                return false;
            }
        }

        requestCounts.put(clientIp, currentTimeMillis);
        return true;
    }
}

然后,在Spring Boot應(yīng)用的配置類中注冊(cè)這個(gè)攔截器:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    private RateLimitingInterceptor rateLimitingInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(rateLimitingInterceptor).addPathPatterns("/api/**");
    }
}

使用Bucket4j實(shí)現(xiàn)Rate Limiting

首先,在項(xiàng)目中引入Bucket4j依賴:

<dependency>
    <groupId>com.github.vladimir-bukhtoyarov</groupId>
    <artifactId>bucket4j-core</artifactId>
    <version>7.0.0</version>
</dependency>

然后,創(chuàng)建一個(gè)自定義的過濾器類,并在其中實(shí)現(xiàn)限流邏輯:

import io.github.bucket4j.Bandwidth;
import io.github.bucket4j.Bucket;
import io.github.bucket4j.Bucket4j;
import io.github.bucket4j.Refill;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.Duration;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

public class Bucket4jRateLimitingFilter implements Filter {
    private final ConcurrentMap<String, Bucket> buckets = new ConcurrentHashMap<>();

    @

Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 初始化過濾器
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;

        String clientIp = httpRequest.getRemoteAddr();
        Bucket bucket = buckets.computeIfAbsent(clientIp, this::newBucket);

        if (bucket.tryConsume(1)) {
            chain.doFilter(request, response);
        } else {
            httpResponse.setStatus(HttpServletResponse.SC_TOO_MANY_REQUESTS);
            httpResponse.getWriter().write("Too many requests");
        }
    }

    private Bucket newBucket(String clientIp) {
        return Bucket4j.builder()
                .addLimit(Bandwidth.classic(60, Refill.greedy(60, Duration.ofMinutes(1))))
                .build();
    }

    @Override
    public void destroy() {
        // 銷毀過濾器
    }
}

然后,在Spring Boot應(yīng)用的配置類中注冊(cè)這個(gè)過濾器:

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FilterConfig {

    @Bean
    public FilterRegistrationBean<Bucket4jRateLimitingFilter> loggingFilter(){
        FilterRegistrationBean<Bucket4jRateLimitingFilter> registrationBean = new FilterRegistrationBean<>();
        
        registrationBean.setFilter(new Bucket4jRateLimitingFilter());
        registrationBean.addUrlPatterns("/api/*");
        
        return registrationBean;
    }
}

最佳實(shí)踐

選擇合適的限流算法

  • 令牌桶算法:適用于需要平滑突發(fā)流量的場(chǎng)景。
  • 漏桶算法:適用于需要嚴(yán)格控制流量的場(chǎng)景。
  • 固定窗口計(jì)數(shù)器:適用于對(duì)簡(jiǎn)單限流要求的場(chǎng)景。
  • 滑動(dòng)窗口計(jì)數(shù)器:適用于需要精確控制限流的場(chǎng)景。

優(yōu)化性能

  • 減少鎖競(jìng)爭(zhēng):在高并發(fā)環(huán)境下,盡量減少鎖的使用,可以采用無鎖數(shù)據(jù)結(jié)構(gòu)或者線程安全的數(shù)據(jù)結(jié)構(gòu)。
  • 緩存結(jié)果:對(duì)于頻繁訪問的數(shù)據(jù),可以考慮進(jìn)行緩存,減少數(shù)據(jù)庫查詢的次數(shù)。
  • 異步處理:對(duì)于耗時(shí)的操作,可以考慮采用異步處理,提高系統(tǒng)的響應(yīng)速度。

記錄日志和監(jiān)控

  • 記錄訪問日志:記錄每次接口訪問的詳細(xì)信息,包括請(qǐng)求時(shí)間、IP地址、請(qǐng)求路徑等。
  • 監(jiān)控限流情況:對(duì)限流情況進(jìn)行監(jiān)控,及時(shí)發(fā)現(xiàn)和處理異常流量。
  • 報(bào)警機(jī)制:設(shè)置限流報(bào)警機(jī)制,當(dāng)流量超過預(yù)設(shè)閾值時(shí),及時(shí)報(bào)警。

總結(jié)

本文詳細(xì)介紹了在Spring Boot中實(shí)現(xiàn)接口訪問頻率限制的幾種方法,包括基于過濾器、攔截器和第三方庫Bucket4j的實(shí)現(xiàn)。通過合理的限流策略,可以有效防止惡意攻擊,提升系統(tǒng)的穩(wěn)定性和用戶體驗(yàn)。在實(shí)際應(yīng)用中,選擇合適的限流算法和實(shí)現(xiàn)方式,并結(jié)合業(yè)務(wù)需求進(jìn)行優(yōu)化,是確保系統(tǒng)高效運(yùn)行的關(guān)鍵。

以上就是SpringBoot接口訪問頻率限制的實(shí)現(xiàn)方式的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot接口訪問頻率限制的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java 堆內(nèi)存分區(qū)的實(shí)現(xiàn)示例

    Java 堆內(nèi)存分區(qū)的實(shí)現(xiàn)示例

    本文主要介紹了Java 堆內(nèi)存分區(qū)的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-04-04
  • eclipse的web項(xiàng)目實(shí)現(xiàn)Javaweb購物車的方法

    eclipse的web項(xiàng)目實(shí)現(xiàn)Javaweb購物車的方法

    這篇文章主要介紹了eclipse的web項(xiàng)目實(shí)現(xiàn)Javaweb購物車的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • 詳解java如何正確使用volatile

    詳解java如何正確使用volatile

    這篇文章給大家分享了java如何正確使用volatile的相關(guān)知識(shí)點(diǎn)內(nèi)容,有興趣的朋友可以參考學(xué)習(xí)下。
    2018-07-07
  • java遞歸實(shí)現(xiàn)復(fù)制一個(gè)文件夾下所有文件功能

    java遞歸實(shí)現(xiàn)復(fù)制一個(gè)文件夾下所有文件功能

    這篇文章主要介紹了java遞歸實(shí)現(xiàn)復(fù)制一個(gè)文件夾下所有文件功能n次,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-08-08
  • SpringBoot實(shí)現(xiàn)發(fā)送郵件功能

    SpringBoot實(shí)現(xiàn)發(fā)送郵件功能

    這篇文章主要介紹了SpringBoot 發(fā)送郵件功能實(shí)現(xiàn),本文以163郵箱為例通過這個(gè)小案例給大家介紹,需要的朋友可以參考下
    2019-12-12
  • Spring實(shí)戰(zhàn)之屬性覆蓋占位符配置器用法示例

    Spring實(shí)戰(zhàn)之屬性覆蓋占位符配置器用法示例

    這篇文章主要介紹了Spring實(shí)戰(zhàn)之屬性覆蓋占位符配置器用法,結(jié)合實(shí)例形式分析了Spring屬性覆蓋占位符配置器相關(guān)原理、配置與使用技巧,需要的朋友可以參考下
    2019-12-12
  • Java實(shí)現(xiàn)Word、Excel、PDF文件在線預(yù)覽幾種實(shí)現(xiàn)方式

    Java實(shí)現(xiàn)Word、Excel、PDF文件在線預(yù)覽幾種實(shí)現(xiàn)方式

    在Web開發(fā)中,經(jīng)常需要實(shí)現(xiàn)文件的在線預(yù)覽功能,比如預(yù)覽PDF、Word、Excel等文檔格式,這篇文章主要介紹了Java實(shí)現(xiàn)Word、Excel、PDF文件在線預(yù)覽幾種實(shí)現(xiàn)方式的相關(guān)資料,需要的朋友可以參考下
    2025-12-12
  • Java?集合框架?Queue?和?Stack?體系

    Java?集合框架?Queue?和?Stack?體系

    這篇文章主要介紹了Java?集合框架Queue和Stack體系,Stack?繼承自Vector,并拓展了五個(gè)允許將容器視為棧結(jié)構(gòu)的操作,Queue接口定義了隊(duì)列的能力,它繼承自Collection,更多相關(guān)內(nèi)容需要得小伙伴可以參考一下
    2022-06-06
  • 詳解Java枚舉與接口常量和類常量的區(qū)別

    詳解Java枚舉與接口常量和類常量的區(qū)別

    這篇文章主要為大家詳細(xì)介紹了Java中枚舉與接口常量、類常量有什么區(qū)別,文中的示例代碼講解詳細(xì),具有一定的參考價(jià)值,感興趣的可以了解一下
    2022-10-10
  • Spring Boot+Nginx+MySQL容器化實(shí)戰(zhàn)指南

    Spring Boot+Nginx+MySQL容器化實(shí)戰(zhàn)指南

    這篇文章主要介紹了Spring Boot+Nginx+MySQL容器化實(shí)戰(zhàn)指南,本文通過思路代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2026-03-03

最新評(píng)論

珲春市| 抚远县| 江城| 容城县| 沙洋县| 手游| 新营市| 密云县| 福海县| 土默特左旗| 南宫市| 米脂县| 安溪县| 绥江县| 吉首市| 南皮县| 舒兰市| 华池县| 桂阳县| 长阳| 长垣县| 公主岭市| 商南县| 呼玛县| 乌鲁木齐县| 文昌市| 卓资县| 开鲁县| 陵川县| 舒城县| 潼南县| 措美县| 二连浩特市| 即墨市| 南康市| 兴隆县| 武清区| 花莲县| 中西区| 林芝县| 扶风县|