SpringBoot單機(jī)限流的實(shí)現(xiàn)
谷歌的 RateLimiter 介紹
使用谷歌的 guava 包中 RateLimiter 類來(lái)實(shí)現(xiàn),先來(lái)介紹一個(gè)這個(gè)類:
- RateLimiter 是一個(gè)頻率限制器,通過(guò)配置頻率來(lái)發(fā)放許可,如果 1 秒內(nèi)可以訪問(wèn)十次,那么這十次許可發(fā)送的間隔是完全相同的
- 并發(fā)使用是安全的
- RateLimiter 還可以去配置先處于一個(gè)預(yù)熱器,每秒增加發(fā)放的許可知道達(dá)到穩(wěn)定的頻率
- RateLimiter 不影響請(qǐng)求本身的節(jié)流,而是影響下一次請(qǐng)求的節(jié)流,比如當(dāng)前任務(wù)如果占用許可較多,到達(dá) RateLimiter 之后,會(huì)立即占用,當(dāng)下一個(gè)請(qǐng)求到達(dá) RateLimiter 時(shí)就會(huì)經(jīng)歷節(jié)流,因?yàn)樯弦粋€(gè)請(qǐng)求已經(jīng)占用大量的許可。
一個(gè)小示例用法,如果想要發(fā)送一組數(shù)據(jù),我們限制他在 5kb 每秒:
// 給每一個(gè)字節(jié)發(fā)放 1 個(gè)許可,限制在 5kb 每秒的話,只需要每秒發(fā)放 5000 個(gè)許可即可 final RateLimiter rateLimiter = RateLimiter.create(5000.0); void submitPacket(byte[] packet) { rateLimiter.acquire(packet.length); networkService.send(packet); }
使用 AOP 實(shí)現(xiàn)單機(jī)限流
實(shí)現(xiàn)步驟:
- 定義切面,攔截 Controller 層方法
- 創(chuàng)建一個(gè) RateLimiter,定義訪問(wèn)頻率
- 當(dāng)執(zhí)行方法時(shí),發(fā)放一個(gè)許可,如果拿不到許可,直接攔截 Controller 層方法的執(zhí)行,返回一個(gè)訪問(wèn)頻繁的提示
Controller
@RestController @RequestMapping("/rate") public class RateController { @GetMapping public String testRate() { return "測(cè)試 Rate "; } }
切面
@Component @Aspect public class ServiceLogAspect { ? ? /** ? ? ?* 對(duì) controller 限流 ? ? ?*/ ? ? @Pointcut("execution(* com.javagpt.back.controller.*.*(..))") ? ? public void rateLimitPointCut() {} ? ? private static final RateLimiter rateLimiter = RateLimiter.create(10); ? ? @SneakyThrows // 使用之后不需要拋出異常,lombok會(huì)自動(dòng)在編譯時(shí)加上try/catch ? ? @Around("rateLimitPointCut()") ? ? public Object rateLimit(ProceedingJoinPoint joinPoint) { ? ? ? ? double rate = rateLimiter.getRate(); ? ? ? ? System.out.println(rate); ? ? ? ? if (rateLimiter.tryAcquire()) { ? ? ? ? ? ? return joinPoint.proceed(); ? ? ? ? } else { ? ? ? ? ? ? // 如果超出限流次數(shù),攔截方法的執(zhí)行,注意這里返回的對(duì)象要和 Controller 方法的返回對(duì)象類型相同,否則會(huì)報(bào)錯(cuò) ? ? ? ? ? ? return "訪問(wèn)太過(guò)頻繁"; ? ? ? ? } ? ? } }
到此這篇關(guān)于SpringBoot單機(jī)限流的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)SpringBoot單機(jī)限流內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 基于SpringBoot+Redis實(shí)現(xiàn)一個(gè)簡(jiǎn)單的限流器
- SpringBoot使用Redis對(duì)用戶IP進(jìn)行接口限流的項(xiàng)目實(shí)踐
- SpringBoot使用Redis對(duì)用戶IP進(jìn)行接口限流的示例詳解
- SpringBoot Redis用注釋實(shí)現(xiàn)接口限流詳解
- SpringBoot如何使用自定義注解實(shí)現(xiàn)接口限流
- 使用SpringBoot?+?Redis?實(shí)現(xiàn)接口限流的方式
- Springboot+Redis實(shí)現(xiàn)API接口限流的示例代碼
- Spring Boot高可用限流三種實(shí)現(xiàn)解決方案
相關(guān)文章
Java入門基礎(chǔ)之常規(guī)的命名方法和變量的值及其引用
這篇文章主要介紹了Java的命名方法和變量的值及其引用,是Java入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-09-09SpringBoot集成Nacos的項(xiàng)目實(shí)踐
本文主要介紹了SpringBoot集成Nacos的項(xiàng)目實(shí)踐,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07Mybatis如何通過(guò)注解開啟使用二級(jí)緩存
這篇文章主要介紹了Mybatis基于注解開啟使用二級(jí)緩存,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-11-11Springboot整合Freemarker的實(shí)現(xiàn)詳細(xì)過(guò)程
這篇文章主要介紹了Springboot整合Freemarker的實(shí)現(xiàn)詳細(xì)過(guò)程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12SpringCloudGateway開發(fā)過(guò)程解析
這篇文章主要介紹了SpringCloudGateway開發(fā)過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-12-12Idea自動(dòng)生成Entity實(shí)現(xiàn)過(guò)程詳解
這篇文章主要介紹了Idea自動(dòng)生成Entity實(shí)現(xiàn)過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09