国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - spring cloud gateway 限流的實現與原理

spring cloud gateway 限流的實現與原理

2021-06-23 13:48Forezp Java教程

這篇文章主要介紹了spring cloud gateway 限流的實現與原理,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

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

常見的限流方式,比如hystrix適用線程池隔離,超過線程池的負載,走熔斷的邏輯。在一般應用服務器中,比如tomcat容器也是通過限制它的線程數來控制并發的;也有通過時間窗口的平均速度來控制流量。常見的限流緯度有比如通過ip來限流、通過uri來限流、通過用戶訪問頻次來限流。

一般限流都是在網關這一層做,比如nginx、openresty、kong、zuul、spring cloud gateway等;也可以在應用層通過aop這種方式去做限流。

本文詳細探討在 spring cloud gateway 中如何實現限流。

常見的限流算法

計數器算法

計數器算法采用計數器實現限流有點簡單粗暴,一般我們會限制一秒鐘的能夠通過的請求數,比如限流qps為100,算法的實現思路就是從第一個請求進來開始計時,在接下去的1s內,每來一個請求,就把計數加1,如果累加的數字達到了100,那么后續的請求就會被全部拒絕。等到1s結束后,把計數恢復成0,重新開始計數。具體的實現可以是這樣的:對于每次服務調用,可以通過atomiclong#incrementandget()方法來給計數器加1并返回最新值,通過這個最新值和閾值進行比較。這種實現方式,相信大家都知道有一個弊端:如果我在單位時間1s內的前10ms,已經通過了100個請求,那后面的990ms,只能眼巴巴的把請求拒絕,我們把這種現象稱為“突刺現象”

漏桶算法

漏桶算法為了消除"突刺現象",可以采用漏桶算法實現限流,漏桶算法這個名字就很形象,算法內部有一個容器,類似生活用到的漏斗,當請求進來時,相當于水倒入漏斗,然后從下端小口慢慢勻速的流出。不管上面流量多大,下面流出的速度始終保持不變。不管服務調用方多么不穩定,通過漏桶算法進行限流,每10毫秒處理一次請求。因為處理的速度是固定的,請求進來的速度是未知的,可能突然進來很多請求,沒來得及處理的請求就先放在桶里,既然是個桶,肯定是有容量上限,如果桶滿了,那么新進來的請求就丟棄。

spring cloud gateway 限流的實現與原理

在算法實現方面,可以準備一個隊列,用來保存請求,另外通過一個線程池(scheduledexecutorservice)來定期從隊列中獲取請求并執行,可以一次性獲取多個并發執行。

這種算法,在使用過后也存在弊端:無法應對短時間的突發流量。

令牌桶算法

從某種意義上講,令牌桶算法是對漏桶算法的一種改進,桶算法能夠限制請求調用的速率,而令牌桶算法能夠在限制調用的平均速率的同時還允許一定程度的突發調用。在令牌桶算法中,存在一個桶,用來存放固定數量的令牌。算法中存在一種機制,以一定的速率往桶中放令牌。每次請求調用需要先獲取令牌,只有拿到令牌,才有機會繼續執行,否則選擇選擇等待可用的令牌、或者直接拒絕。放令牌這個動作是持續不斷的進行,如果桶中令牌數達到上限,就丟棄令牌,所以就存在這種情況,桶中一直有大量的可用令牌,這時進來的請求就可以直接拿到令牌執行,比如設置qps為100,那么限流器初始化完成一秒后,桶中就已經有100個令牌了,這時服務還沒完全啟動好,等啟動完成對外提供服務時,該限流器可以抵擋瞬時的100個請求。所以,只有桶中沒有令牌時,請求才會進行等待,最后相當于以一定的速率執行。

spring cloud gateway 限流的實現與原理

實現思路:可以準備一個隊列,用來保存令牌,另外通過一個線程池定期生成令牌放到隊列中,每來一個請求,就從隊列中獲取一個令牌,并繼續執行。

spring cloud gateway限流

在spring cloud gateway中,有filter過濾器,因此可以在“pre”類型的filter中自行實現上述三種過濾器。但是限流作為網關最基本的功能,spring cloud gateway官方就提供了requestratelimitergatewayfilterfactory這個類,適用redis和lua腳本實現了令牌桶的方式。具體實現邏輯在requestratelimitergatewayfilterfactory類中,lua腳本在如下圖所示的文件夾中:

spring cloud gateway 限流的實現與原理

具體源碼不打算在這里講述,讀者可以自行查看,代碼量較少,先以案例的形式來講解如何在spring cloud gateway中使用內置的限流過濾器工廠來實現限流。

首先在工程的pom文件中引入gateway的起步依賴和redis的reactive依賴,代碼如下:

?
1
2
3
4
5
6
7
8
9
<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>

在配置文件中做以下的配置:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
server:
 port: 8081
spring:
 cloud:
  gateway:
   routes:
   - id: limit_route
    uri: http://httpbin.org:80/get
    predicates:
    - after=2017-01-20t17:42:47.789-07:00[america/denver]
    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

在上面的配置文件,指定程序的端口為8081,配置了 redis的信息,并配置了requestratelimiter的限流過濾器,該過濾器需要配置三個參數:

  • burstcapacity,令牌桶總容量。
  • replenishrate,令牌桶每秒填充平均速率。
  • key-resolver,用于限流的鍵的解析器的 bean 對象的名字。它使用 spel 表達式根據#{@beanname}從 spring 容器中獲取 bean 對象。

keyresolver需要實現resolve方法,比如根據hostname進行限流,則需要用hostaddress去判斷。實現完keyresolver之后,需要將這個類的bean注冊到ioc容器中。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
public class hostaddrkeyresolver implements keyresolver {
 
  @override
  public mono<string> resolve(serverwebexchange exchange) {
    return mono.just(exchange.getrequest().getremoteaddress().getaddress().gethostaddress());
  }
 
}
 
 @bean
  public hostaddrkeyresolver hostaddrkeyresolver() {
    return new hostaddrkeyresolver();
  }

可以根據uri去限流,這時keyresolver代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
public class urikeyresolver implements keyresolver {
 
  @override
  public mono<string> resolve(serverwebexchange exchange) {
    return mono.just(exchange.getrequest().geturi().getpath());
  }
 
}
 
 @bean
  public urikeyresolver urikeyresolver() {
    return new urikeyresolver();
  }

也可以以用戶的維度去限流:

?
1
2
3
4
@bean
  keyresolver userkeyresolver() {
    return exchange -> mono.just(exchange.getrequest().getqueryparams().getfirst("user"));
  }

用jmeter進行壓測,配置10thread去循環請求lcoalhost:8081,循環間隔1s。從壓測的結果上看到有部分請求通過,由部分請求失敗。通過redis客戶端去查看redis中存在的key。如下:

spring cloud gateway 限流的實現與原理

可見,requestratelimiter是使用redis來進行限流的,并在redis中存儲了2個key。關注這兩個key含義可以看lua源代碼。

源碼下載

https://github.com/forezp/springcloudlearning/tree/master/sc-f-gateway-limiter

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:https://segmentfault.com/a/1190000017421460

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 91视频在线免费观看 | 亚洲另类视频 | 精品一区二区三区免费视频 | 日韩欧美中文在线观看 | 亚洲精品久久久一区二区三区 | 激情免费视频 | 亚洲一区二区中文字幕 | 日韩一区二区精品 | 九九热这里都是精品 | 欧美国产精品一区二区三区 | 依人在线免费视频 | av免费网站| 亚洲免费在线视频 | 综合色爱 | 91国内精品久久 | 成人天堂网 | 午夜精品一区二区三区在线视频 | 亚洲国产精品久久 | 综合亚洲精品 | 欧美一区二区三区精品 | 久热免费在线观看 | 国产三级精品在线 | 日韩a | 亚洲精品一级 | 久久国产精品一区二区 | 97精品国产一区二区三区 | 欧美视频免费 | 午夜精品久久久久久久久久久久久 | 粉嫩欧美一区二区三区高清影视 | 欧美精品三区 | 中文字幕视频二区 | 亚洲精品久久久久久下一站 | 在线观看av片 | 免费观看一级特黄欧美大片 | 亚洲a精品| 久久精品亚洲精品 | 91精彩视频在线观看 | 精品在线一区二区 | 精品黄色在线 | 欧美激情视频一区二区三区在线播放 | 国产一区二区三区免费播放 |