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

SpringBoot中基于AOP和Semaphore實現(xiàn)API限流

 更新時間:2024年10月20日 09:04:05   作者:碼到三十五  
調用速率限制是 Web API 中的常見要求,旨在防止濫用并確保公平使用資源,借助Spring Boot 中的 AOP,我們可以通過攔截方法調用并限制在特定時間范圍內允許的請求數(shù)量來實現(xiàn)速率限制,需要的朋友可以參考下

為了在 Spring Boot 中使用 AOP 實現(xiàn)速率限制:

  • 定義自定義注釋來標記應該限速的方法。
  • 創(chuàng)建一個方面類,攔截用自定義注釋注釋的方法調用。
  • 使用速率限制器組件來跟蹤和執(zhí)行速率限制。
  • 處理速率限制超出的情況,如通過拋出自定義異常。

Spring Boot API 中的速率限制

可以使用各種技術在 Spring Boot API 中實現(xiàn)速率限制。一種常見的方法是使用 Spring AOP來攔截傳入的請求并實施速率限制。

步驟 1 - 定義速率限制配置

創(chuàng)建一個配置類,在其中定義速率限制參數(shù),例如允許的請求數(shù)和時間段。

@Configuration
public class RateLimitConfig {
    @Value("${rate.limit.requests}")
    private int requests;

    @Value("${rate.limit.seconds}")
    private int seconds;

    // Getters and setters
}

步驟 2 - 創(chuàng)建速率限制方面

使用 Spring AOP 實現(xiàn)一個方面來攔截方法調用并強制執(zhí)行速率限制。

@Aspect
@Component
public class RateLimitAspect {
    @Autowired
    private RateLimitConfig rateLimitConfig;

    @Autowired
    private RateLimiter rateLimiter;

    @Around("@annotation(RateLimited)")
    public Object enforceRateLimit(ProceedingJoinPoint joinPoint) throws Throwable {
        String key = getKey(joinPoint);
        if (!rateLimiter.tryAcquire(key, rateLimitConfig.getRequests(), rateLimitConfig.getSeconds())) {
            throw new RateLimitExceededException("Rate limit exceeded");
        }
        return joinPoint.proceed();
    }

    private String getKey(ProceedingJoinPoint joinPoint) {
        //為正在調用的方法生成唯一密鑰
        //方法簽名、用戶ID、IP地址等。

    }
}

步驟 3 — 定義 RateLimited 注釋

創(chuàng)建自定義注釋來標記應受速率限制的方法。

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
  public @interface RateLimited {
}

步驟 4 - 實施速率限制器

創(chuàng)建速率限制器組件,使用令牌桶算法或任何其他合適的算法來管理速率限制。

@Component
public class RateLimiter {
    private final Map<String,RateLimitedSemaphore> semaphores = new ConcurrentHashMap<>();

    public boolean tryAcquire(String key, int requests, int seconds) {
        
        long currentTime = System.currentTimeMillis();

        // 計算時間窗口
        long startTime = currentTime - seconds * 1000;

        // 過期刪除
        cleanupExpiredEntries(startTime);

        // 獲取semaphore 
        RateLimitedSemaphore semaphore = semaphores.computeIfAbsent(key, k -> {
            RateLimitedSemaphore newSemaphore = new RateLimitedSemaphore(requests);
            newSemaphore.setLastAcquireTime(currentTime); // Set last acquire time
            return newSemaphore;
        });

        // 校驗 semaphore 
        boolean acquired = semaphore.tryAcquire();
        if (acquired) {
            semaphore.setLastAcquireTime(currentTime); 
            // 更新
        }
        return acquired;
    }

    private void cleanupExpiredEntries(long startTime) {
        Iterator<Map.Entry<String, RateLimitedSemaphore>> iterator = semaphores.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, RateLimitedSemaphore> entry = iterator.next();
            String key = entry.getKey();
            RateLimitedSemaphore semaphore = entry.getValue();
            if (semaphore.getLastAcquireTime() < startTime) {
                iterator.remove();
            }
        }
    }

    private class RateLimitedSemaphore extends Semaphore {
        private volatile long lastAcquireTime;

        public RateLimitedSemaphore(int permits) {
            super(permits);
        }

        public long getLastAcquireTime() {
            return lastAcquireTime;
        }

        public void setLastAcquireTime(long lastAcquireTime) {
            this.lastAcquireTime = lastAcquireTime;
        }
    }
}

步驟 5 - 注釋控制器方法

用注解來注釋應該進行速率限制的控制器方法 @RateLimited。

@RestController
public class MyController {
    @RateLimited
    @GetMapping("/api/resource")
    public ResponseEntity<String> getResource() {
        // Implementation
    }
}

步驟 6 - 配置速率限制屬性

application.properties在您的 或 中配置速率限制屬性 application.yml。

rate.limit.requests=10
rate.limit.seconds=60

要按 IP 地址限制請求,可以從傳入請求中提取 IP 地址并將其用作速率限制的密鑰:

private String getKey(HttpServletRequest request) {
    String ipAddress = request.getRemoteAddr();
    return ipAddress; //用ID做key
}

還需要修改enforceRateLimit 中的方法 RateLimitAspect 以將對象傳遞 HttpServletRequest 給 getKey 方法:

@Around("@annotation(RateLimited)")
public Object enforceRateLimit(ProceedingJoinPoint joinPoint) throws Throwable {
   
    ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
    HttpServletRequest request = requestAttributes.getRequest();

    String key = getKey(request);
    if (!rateLimiter.tryAcquire(key, rateLimitConfig.getRequests(), rateLimitConfig.getSeconds())) {
        throw new RateLimitExceededException("Rate limit exceeded");
    }
    return joinPoint.proceed();
}

以上就是SpringBoot中基于AOP和Semaphore實現(xiàn)API限流的詳細內容,更多關于SpringBoot實現(xiàn)API限流的資料請關注腳本之家其它相關文章!

相關文章

  • Spring?question問題小結

    Spring?question問題小結

    在AppConfig配置類中,通過@Bean注解創(chuàng)建了Service和Controller的實例,Spring會自動將這些實例納入容器的管理,并處理它們之間的依賴關系,本文給大家介紹Spring?question問題小結,感興趣的朋友跟隨小編一起看看吧
    2023-10-10
  • SpringBoot AOP注解失效問題排查與解決(調用內部方法)

    SpringBoot AOP注解失效問題排查與解決(調用內部方法)

    這篇文章主要介紹了SpringBoot AOP注解失效問題排查與解決(調用內部方法),文中通過代碼示例介紹的非常詳細,對大家的學習或工作有一定的幫助,需要的朋友可以參考下
    2024-04-04
  • MyBatis-Plus枚舉和自定義主鍵ID的實現(xiàn)步驟

    MyBatis-Plus枚舉和自定義主鍵ID的實現(xiàn)步驟

    這篇文章主要給大家介紹了關于MyBatis-Plus枚舉和自定義主鍵ID的相關資料,文中通過實例代碼以及圖文介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2022-02-02
  • Springboot深入講解nocos的整合與使用

    Springboot深入講解nocos的整合與使用

    Nacos?是阿里巴巴推出來的一個新開源項目,這是一個更易于構建云原生應用的動態(tài)服務發(fā)現(xiàn)、配置管理和服務管理平臺,在項目開發(fā)過程中,我們經常使用nacos作為配置中心和注冊中心。本文章我們就從代碼層面研究下springboot是如何整合nacos使用的
    2022-07-07
  • Gradle生成Jar的兩種方式小結

    Gradle生成Jar的兩種方式小結

    本文介紹使用Gradle創(chuàng)建不可執(zhí)行及可執(zhí)行的Jar包,包括將依賴Jar放入lib文件夾的方法,以及如何生成包含所有依賴的單一Jar文件,適用于SpringBoot和其他非SpringBoot項目,感興趣的可以了解一下
    2025-09-09
  • java 使用線程監(jiān)控文件目錄變化的實現(xiàn)方法

    java 使用線程監(jiān)控文件目錄變化的實現(xiàn)方法

    這篇文章主要介紹了java 使用線程監(jiān)控文件目錄變化的實現(xiàn)方法的相關資料,希望通過本文能幫助到大家,需要的朋友可以參考下
    2017-10-10
  • 統(tǒng)一建模語言_動力節(jié)點Java學院整理

    統(tǒng)一建模語言_動力節(jié)點Java學院整理

    這篇文章主要介紹了統(tǒng)一建模語言的相關知識,非常不錯,具有參考借鑒價值,需要的的朋友參考下吧
    2017-06-06
  • Java讓多線程按順序執(zhí)行的幾種方法

    Java讓多線程按順序執(zhí)行的幾種方法

    本文主要介紹了Java讓多線程按順序執(zhí)行的幾種方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-05-05
  • java商城項目實戰(zhàn)之購物車功能實現(xiàn)

    java商城項目實戰(zhàn)之購物車功能實現(xiàn)

    這篇文章主要為大家詳細介紹了java商城項目實戰(zhàn)之購物車功能實現(xiàn),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-04-04
  • Java語言中4種內部類的超詳細講解

    Java語言中4種內部類的超詳細講解

    這篇文章主要給大家介紹了關于Java語言中4種內部類的超詳細講解,內部類可以分為:實例內部類、靜態(tài)內部類和成員內部類,每種內部類都有它特定的一些特點,文中介紹的非常詳細,需要的朋友可以參考下
    2023-04-04

最新評論

新乐市| 吉隆县| 德化县| 邯郸市| 治县。| 永宁县| 区。| 龙江县| 扶沟县| 太保市| 南和县| 东台市| 沈丘县| 威信县| 乌鲁木齐县| 阳东县| 通道| 聂荣县| 揭西县| 和政县| 北辰区| 建水县| 高要市| 曲周县| 望城县| 游戏| 奎屯市| 监利县| 林西县| 新兴县| 应用必备| 延川县| 芮城县| 阳春市| 苗栗市| 凤冈县| 诸暨市| 广德县| 沁阳市| 高青县| 南江县|