中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Spring Cloud Gateway 之 限流

發布時間:2020-08-03 14:22:06 來源:網絡 閱讀:675 作者:程序員果果 欄目:編程語言

簡介

在高并發的系統中,往往需要在系統中做限流,一方面是為了防止大量的請求使服務器過載,導致服務不可用,另一方面是為了防止網絡***。

一般開發高并發系統常見的限流有:限制總并發數(比如數據庫連接池、線程池)、限制瞬時并發數(如 nginx 的 limit_conn 模塊,用來限制瞬時并發連接數)、限制時間窗口內的平均速率(如 Guava 的 RateLimiter、nginx 的 limit_req 模塊,限制每秒的平均速率);其他還有如限制遠程接口調用速率、限制 MQ 的消費速率。另外還可以根據網絡連接數、網絡流量、CPU 或內存負載等來限流。

限流算法

計數器

簡單的做法是維護一個單位時間內的 計數器,每次請求計數器加1,當單位時間內計數器累加到大于設定的閾值,則之后的請求都被拒絕,直到單位時間已經過去,再將 計數器 重置為零。此方式有個弊端:如果在單位時間1s內允許100個請求,在10ms已經通過了100個請求,那后面的990ms,只能眼巴巴的把請求拒絕,我們把這種現象稱為“突刺現象”。

常用的更平滑的限流算法有兩種:漏桶算法令牌桶算法。下面介紹下二者。

漏桶算法

漏桶算法思路很簡單,水(請求)先進入到漏桶里,漏桶以一定的速度出水(接口有響應速率),當水流入速度過大會直接溢出(訪問頻率超過接口響應速率),然后就拒絕請求,可以看出漏桶算法能強行限制數據的傳輸速率。

Spring Cloud Gateway 之 限流

可見這里有兩個變量,一個是桶的大小,支持流量突發增多時可以存多少的水(burst),另一個是水桶漏洞的大小(rate)。因為漏桶的漏出速率是固定的參數,所以,即使網絡中不存在資源沖突(沒有發生擁塞),漏桶算法也不能使流突發(burst)到端口速率。因此,漏桶算法對于存在突發特性的流量來說缺乏效率。

令牌桶算法

令牌桶算法 和漏桶算法 效果一樣但方向相反的算法,更加容易理解。隨著時間流逝,系統會按恒定 1/QPS 時間間隔(如果 QPS=100,則間隔是 10ms)往桶里加入 Token(想象和漏洞漏水相反,有個水龍頭在不斷的加水),如果桶已經滿了就不再加了。新請求來臨時,會各自拿走一個 Token,如果沒有 Token 可拿了就阻塞或者拒絕服務。

Spring Cloud Gateway 之 限流

令牌桶的另外一個好處是可以方便的改變速度。一旦需要提高速率,則按需提高放入桶中的令牌的速率。一般會定時(比如 100 毫秒)往桶中增加一定數量的令牌,有些變種算法則實時的計算應該增加的令牌的數量。

限流實現

在 Spring Cloud Gateway 上實現限流是個不錯的選擇,只需要編寫一個過濾器就可以了。有了前邊過濾器的基礎,寫起來很輕松。

Spring Cloud Gateway 已經內置了一個RequestRateLimiterGatewayFilterFactory,我們可以直接使用。

目前RequestRateLimiterGatewayFilterFactory的實現依賴于 Redis,所以我們還要引入spring-boot-starter-data-redis-reactive。

pom.xml

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifatId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>

application.yml

server:
  port: 8080
spring:
  cloud:
    gateway:
      routes:
        - id: limit_route
          uri: http://httpbin.org:80/get
          predicates:
          - After=2019-02-26T00:00:00+08:00[Asia/Shanghai]
          filters:
          - name: RequestRateLimiter
            args:
              key-resolver: '#{@hostAddrKeyResolver}'
              redis-rate-limiter.replenishRate: 1
              redis-rate-limiter.burstCapacity: 3
  application:
    name: gateway-limiter
  redis:
    host: localhost
    port: 6379
    database: 0

在上面的配置文件,配置了 redis的信息,并配置了RequestRateLimiter的限流過濾器,該過濾器需要配置三個參數:

  • burstCapacity:令牌桶總容量。
  • replenishRate:令牌桶每秒填充平均速率。
  • key-resolver:用于限流的鍵的解析器的 Bean 對象的名字。它使用 SpEL 表達式根據#{@beanName}從 Spring 容器中獲取 Bean 對象。

IP限流

獲取請求用戶ip作為限流key。

@Bean
public KeyResolver hostAddrKeyResolver() {
    return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getHostName());
}

用戶限流

獲取請求用戶id作為限流key。

@Bean
public KeyResolver userKeyResolver() {
    return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("userId"));
}

接口限流

獲取請求地址的uri作為限流key。

@Bean
KeyResolver apiKeyResolver() {
    return exchange -> Mono.just(exchange.getRequest().getPath().value());
}

歡迎關注我的公眾號《程序員果果》,關注有驚喜~~
Spring Cloud Gateway 之 限流

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

宁远县| 镇赉县| 内丘县| 兴隆县| 林州市| 无锡市| 定州市| 桂阳县| 凤山市| 巴东县| 天津市| 江永县| 昂仁县| 南京市| 南雄市| 巴里| 湖北省| 车险| 海宁市| 汝州市| 宜阳县| 宁陵县| 丰县| 淮安市| 济南市| 井冈山市| 敖汉旗| 阿拉尔市| 轮台县| 沐川县| 乐业县| 磐安县| 江华| 凤山县| 论坛| 若羌县| 淮安市| 清徐县| 桐柏县| 昭觉县| 吴江市|