Spring Cloud Gateway 原生支持接口限流該怎么玩

關(guān)于pig:

基于Spring Cloud弛秋、oAuth2.0開發(fā)基于Vue前后分離的開發(fā)平臺(tái)踪区,支持賬號(hào)、短信赤炒、SSO等多種登錄氯析,提供配套視頻開發(fā)教程。

碼云地址:https://gitee.com/log4j/pig

關(guān)于 Spring Cloud Gateway

SpringCloudGateway是Spring官方基于Spring 5.0莺褒,Spring Boot 2.0和Project Reactor等技術(shù)開發(fā)的網(wǎng)關(guān)掩缓,Spring云網(wǎng)關(guān)旨在提供一種簡(jiǎn)單而有效的路由API的方法。Spring Cloud Gateway作為Spring Cloud生態(tài)系中的網(wǎng)關(guān)遵岩,目標(biāo)是替代Netflix ZUUL你辣,其不僅提供統(tǒng)一的路由方式,并且基于Filter鏈的方式提供了網(wǎng)關(guān)基本的功能旷余,例如:安全绢记,監(jiān)控/埋點(diǎn),和限流等正卧。

zuul如何實(shí)現(xiàn)多維度限流請(qǐng)參考我的博客

Zuul:構(gòu)建高可用網(wǎng)關(guān)之多維度限流

開始Gateway 限流

POM 依賴

<!--spring cloud gateway依賴-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!--基于 reactive stream 的redis -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>

配置按照請(qǐng)求IP 的限流

spring:
  cloud:
    gateway:
      routes:
      - id: requestratelimiter_route
        uri: lb://pigx-upms
        order: 10000
        predicates:
        - Path=/admin/**
        filters:
        - name: RequestRateLimiter
          args:
            redis-rate-limiter.replenishRate: 1  # 令牌桶的容積
            redis-rate-limiter.burstCapacity: 3  # 流速 每秒
            key-resolver: "#{@remoteAddrKeyResolver}" #SPEL表達(dá)式去的對(duì)應(yīng)的bean
        - StripPrefix=1

配置bean蠢熄,多維度限流量的入口

/**
* 自定義限流標(biāo)志的key,多個(gè)維度可以從這里入手
* exchange對(duì)象中獲取服務(wù)ID炉旷、請(qǐng)求信息签孔,用戶信息等
*/
@Bean
KeyResolver remoteAddrKeyResolver() {
    return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getHostName());
}

OK 完成叉讥。

壓力測(cè)試

并發(fā)5個(gè)線程。


image

Redis 數(shù)據(jù)變化

我們使用redis的monitor 命令饥追,實(shí)時(shí)查看redis 的操作情況图仓。
會(huì)發(fā)現(xiàn)在redis中會(huì)操作兩個(gè)key

  • request_rate_limiter.{xxx}.timestamp
  • request_rate_limiter.{xxx}.tokens


    image

實(shí)現(xiàn)原理

image

Spring Cloud Gateway 默認(rèn)實(shí)現(xiàn) Redis限流,如果擴(kuò)展只需要實(shí)現(xiàn)ratelimter接口即可但绕。

RedisRateLimter 的核心代碼救崔,判斷是否取到令牌的實(shí)現(xiàn),通過調(diào)用 redis的LUA 腳本捏顺。

public Mono<Response> isAllowed(String routeId, String id) {
    Config routeConfig = getConfig().getOrDefault(routeId, defaultConfig);
    int replenishRate = routeConfig.getReplenishRate();
    int burstCapacity = routeConfig.getBurstCapacity();

    try {
        List<String> keys = getKeys(id);
        returns unixtime in seconds.
        List<String> scriptArgs = Arrays.asList(replenishRate + "", burstCapacity + "",
                Instant.now().getEpochSecond() + "", "1");
        // 這里是核心六孵,執(zhí)行redis 的LUA 腳本。
        Flux<List<Long>> flux =
        this.redisTemplate.execute(this.script, keys, scriptArgs);
        return flux.onErrorResume(throwable -> Flux.just(Arrays.asList(1L, -1L)))
                .reduce(new ArrayList<Long>(), (longs, l) -> {
                    longs.addAll(l);
                    return longs;
                }) .map(results -> {
                    boolean allowed = results.get(0) == 1L;
                    Long tokensLeft = results.get(1);

                    Response response = new Response(allowed, getHeaders(routeConfig, tokensLeft));

                    if (log.isDebugEnabled()) {
                        log.debug("response: " + response);
                    }
                    return response;
                });
    }
    catch (Exception e) {
        log.error("Error determining if user allowed from redis", e);
    }
    return Mono.just(new Response(true, getHeaders(routeConfig, -1L)));
}

LUA 腳本

image
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末幅骄,一起剝皮案震驚了整個(gè)濱河市劫窒,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌拆座,老刑警劉巖主巍,帶你破解...
    沈念sama閱讀 211,290評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異挪凑,居然都是意外死亡孕索,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門岖赋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來檬果,“玉大人,你說我怎么就攤上這事唐断⊙〖梗” “怎么了?”我有些...
    開封第一講書人閱讀 156,872評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵脸甘,是天一觀的道長(zhǎng)恳啥。 經(jīng)常有香客問我,道長(zhǎng)丹诀,這世上最難降的妖魔是什么钝的? 我笑而不...
    開封第一講書人閱讀 56,415評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮铆遭,結(jié)果婚禮上硝桩,老公的妹妹穿的比我還像新娘。我一直安慰自己枚荣,他們只是感情好碗脊,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評(píng)論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著橄妆,像睡著了一般衙伶。 火紅的嫁衣襯著肌膚如雪祈坠。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,784評(píng)論 1 290
  • 那天矢劲,我揣著相機(jī)與錄音赦拘,去河邊找鬼。 笑死芬沉,一個(gè)胖子當(dāng)著我的面吹牛躺同,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播花嘶,決...
    沈念sama閱讀 38,927評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼笋籽,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼蹦漠!你這毒婦竟也來了椭员?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,691評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤笛园,失蹤者是張志新(化名)和其女友劉穎隘击,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體研铆,經(jīng)...
    沈念sama閱讀 44,137評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡埋同,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評(píng)論 2 326
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了棵红。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片凶赁。...
    茶點(diǎn)故事閱讀 38,622評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖逆甜,靈堂內(nèi)的尸體忽然破棺而出虱肄,到底是詐尸還是另有隱情,我是刑警寧澤交煞,帶...
    沈念sama閱讀 34,289評(píng)論 4 329
  • 正文 年R本政府宣布咏窿,位于F島的核電站,受9級(jí)特大地震影響素征,放射性物質(zhì)發(fā)生泄漏集嵌。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評(píng)論 3 312
  • 文/蒙蒙 一御毅、第九天 我趴在偏房一處隱蔽的房頂上張望根欧。 院中可真熱鬧,春花似錦端蛆、人聲如沸凤粗。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽侈沪。三九已至揭璃,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間亭罪,已是汗流浹背瘦馍。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留应役,地道東北人情组。 一個(gè)月前我還...
    沈念sama閱讀 46,316評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像箩祥,于是被迫代替她去往敵國(guó)和親院崇。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容