詳解SpringCloudNetflixZuul中的速率限制

Spring Cloud Netflix Zuul是一個包含Netflix Zuul的 開源網關。它為Spring Boot應用程序添加了一些特定功能。不幸的是,開箱即用不提供速率限制。

專注于為中小企業提供成都網站設計、網站制作服務,電腦端+手機端+微信端的三站合一,更高效的管理,為中小企業永興免費做網站提供優質的服務。我們立足成都,凝聚了一批互聯網行業人才,有力地推動了上千余家企業的穩健成長,幫助中小企業通過網站建設實現規模擴充和轉變。

除了Spring Cloud Netflix Zuul依賴項之外,我們還需要將Spring Cloud Zuul RateLimit 添加到我們的應用程序的pom.xml中:

<dependency>
 <groupId>org.springframework.cloud</groupId>
 <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<dependency>
 <groupId>com.marcosbarbero.cloud</groupId>
 <artifactId>spring-cloud-zuul-ratelimit</artifactId>
 <version>2.2.0.RELEASE</version>
</dependency>

首先,讓我們創建幾個REST端點,我們將在其上應用速率限制。

下面是一個簡單的Spring Controller類,有兩個端點:

@Controller
@RequestMapping("/greeting")
public class GreetingController {
 
 @GetMapping("/simple")
 public ResponseEntity<String> getSimple() {
  return ResponseEntity.ok("Hi!");
 }
 
 @GetMapping("/advanced")
 public ResponseEntity<String> getAdvanced() {
  return ResponseEntity.ok("Hello, how you doing?");
 }
}

讓我們在application.yml文件中添加以下Zuul屬性  :

zuul:
 routes:
 serviceSimple:
  path: /greeting/simple
  url: forward:/
 serviceAdvanced:
  path: /greeting/advanced
  url: forward:/
 ratelimit:
 enabled: true
 repository: JPA
 policy-list:
  serviceSimple:
  - limit: 5
   refresh-interval: 60
   type:
   - origin
  serviceAdvanced:
  - limit: 1
   refresh-interval: 2
   type:
   - origin
 strip-prefix: true

在zuul.routes下,我們提供端點詳細信息。在zuul.ratelimit.policy-list下,我們為端點提供速率限制配置。該限屬性指定的時間端點可以在內部被稱為數字刷新間隔。

我們可以看到,我們為serviceSimple  端點添加了每60秒5個請求的速率限制。相比之下,  serviceAdvanced的速率限制為每2秒1個請求。

該類型配置指定其速率限制的方法,以下是可能的值:

  • origin - 基于用戶原始請求的速率限制
  • url - 基于下游服務的請求路徑的速率限制
  • user - 基于經過身份驗證的用戶名或“匿名”的速率限制
  • No value - 充當每項服務的全局配置。要使用這種方法,請不要設置參數'type'

接下來,讓我們測試一下速率限制:

@Test
public void whenRequestNotExceedingCapacity_thenReturnOkResponse() {
 ResponseEntity<String> response = restTemplate.getForEntity(SIMPLE_GREETING, String.class);
 assertEquals(OK, response.getStatusCode());
 
 HttpHeaders headers = response.getHeaders();
 String key = "rate-limit-application_serviceSimple_127.0.0.1";
 
 assertEquals("5", headers.getFirst(HEADER_LIMIT + key));
 assertEquals("4", headers.getFirst(HEADER_REMAINING + key));
 assertEquals("60000", headers.getFirst(HEADER_RESET + key)); 
}

在這里,我們只對一個端點/ greeting / simple進行一次調用。請求成功,因為它在速率限制內。

另一個關鍵點是,對于每個響應,我們返回標頭Header,為我們提供有關速率限制的更多信息。對于上述請求,我們將獲得以下標頭:

X-RateLimit-Limit-rate-limit-application_serviceSimple_127.0.0.1: 5

X-RateLimit-Remaining-rate-limit-application_serviceSimple_127.0.0.1: 4

X-RateLimit-Reset-rate-limit-application_serviceSimple_127.0.0.1: 60000

解釋:

  • X-RateLimit-Limit- [key]:為端點配置 的限制
  • X-RateLimit-Remaining- [key]:  調用端點的剩余嘗試次數
  • X-RateLimit-Reset- [key]:為端點配置 的刷新間隔的剩余毫秒數

另外,如果我們再次立即觸發相同的端點,我們可以得到:

X-RateLimit-Limit-rate-limit-application_serviceSimple_127.0.0.1: 5

X-RateLimit-Remaining-rate-limit-application_serviceSimple_127.0.0.1: 3

X-RateLimit-Reset-rate-limit-application_serviceSimple_127.0.0.1: 57031

請注意減少的剩余嘗試次數和剩余的毫秒數。

讓我們看看當我們超過速率限制時會發生什么:

@Test
public void whenRequestExceedingCapacity_thenReturnTooManyRequestsResponse() throws InterruptedException {
 ResponseEntity<String> response = this.restTemplate.getForEntity(ADVANCED_GREETING, String.class);
 assertEquals(OK, response.getStatusCode());
  
 for (int i = 0; i < 2; i++) {
  response = this.restTemplate.getForEntity(ADVANCED_GREETING, String.class);
 }
 
 assertEquals(TOO_MANY_REQUESTS, response.getStatusCode());
 
 HttpHeaders headers = response.getHeaders();
 String key = "rate-limit-application_serviceAdvanced_127.0.0.1";
 
 assertEquals("1", headers.getFirst(HEADER_LIMIT + key));
 assertEquals("0", headers.getFirst(HEADER_REMAINING + key));
 assertNotEquals("2000", headers.getFirst(HEADER_RESET + key));
 
 TimeUnit.SECONDS.sleep(2);
 
 response = this.restTemplate.getForEntity(ADVANCED_GREETING, String.class);
 assertEquals(OK, response.getStatusCode());
}

在這里,我們快速連續兩次調用,由于我們已將速率限制配置為每2秒一個請求,因此第二個調用將失敗。結果,錯誤代碼429(Too Many Requests)返回給客戶端。以下是達到速率限制時返回的標頭:

X-RateLimit-Limit-rate-limit-application_serviceAdvanced_127.0.0.1: 1

X-RateLimit-Remaining-rate-limit-application_serviceAdvanced_127.0.0.1: 0

X-RateLimit-Reset-rate-limit-application_serviceAdvanced_127.0.0.1: 268

之后,我們休息了2秒鐘。這是為端點配置的刷新間隔。最后,我們再次觸發端點并獲得成功的響應。

自定義密鑰生成器

我們可以使用自定義密鑰生成器自定義響應頭中發送的密鑰。這很有用,因為應用程序可能需要控制除type屬性提供的選項之外的密鑰策略。

例如,這可以通過創建自定義的RateLimitKeyGenerator實現類來完成。我們可以添加更多的限定符或完全不同的東西:

@Bean
public RateLimitKeyGenerator rateLimitKeyGenerator(RateLimitProperties properties,
 RateLimitUtils rateLimitUtils) {
 return new DefaultRateLimitKeyGenerator(properties, rateLimitUtils) {
  @Override
  public String key(HttpServletRequest request, Route route,
   RateLimitProperties.Policy policy) {
   return super.key(request, route, policy) + "_" + request.getMethod();
  }
 };
}

上面的代碼將REST方法名稱附加到鍵。例如:

X-RateLimit-Limit-rate-limit-application_serviceSimple_127.0.0.1_GET: 5

另一個關鍵點是  RateLimitKeyGenerator bean將由spring-cloud-zuul-ratelimit自動配置。

自定義錯誤處理

該框架支持速率限制數據存儲的各種實現。例如,提供了Spring Data JPA和redis。默認情況下,使用DefaultRateLimiterErrorHandler  類將故障記錄為錯誤。

當我們需要以不同方式處理錯誤時,我們可以定義一個自定義的RateLimiterErrorHandler bean:

@Bean
public RateLimiterErrorHandler rateLimitErrorHandler() {
 return new DefaultRateLimiterErrorHandler() {
  @Override
  public void handleSaveError(String key, Exception e) {
   <i>// implementation</i>
  }
 
  @Override
  public void handleFetchError(String key, Exception e) {
   <i>// implementation</i>
  }
 
  @Override
  public void handleError(String msg, Exception e) {
   <i>// implementation</i>
  }
 };
}

與RateLimitKeyGenerator bean 類似  ,也將自動配置RateLimiterErrorHandler bean。

在GitHub上 找到本文的完整代碼

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持創新互聯。

網站標題:詳解SpringCloudNetflixZuul中的速率限制
網頁網址:http://m.kartarina.com/article18/pppjgp.html

成都網站建設公司_創新互聯,為您提供品牌網站制作ChatGPT電子商務網頁設計公司App開發網站建設

廣告

聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯

商城網站建設
主站蜘蛛池模板: 成年轻人电影www无码| 国产精品成人无码久久久| 国产成人无码专区| 无码专区国产精品视频| 中文字幕AV中文字无码亚 | 永久免费AV无码国产网站| 久久久精品天堂无码中文字幕 | yy111111少妇影院无码| 亚洲av无码一区二区三区天堂古代| 成人免费无码大片A毛片抽搐| 国产精品无码专区| 国产无码一区二区在线| 无码av专区丝袜专区| 精品高潮呻吟99av无码视频| 潮喷无码正在播放| 内射无码午夜多人| 日韩放荡少妇无码视频| 精品欧洲av无码一区二区14| 亚洲AV无码一区二区乱孑伦AS| 天天看高清无码一区二区三区| 亚洲av中文无码字幕色不卡| 亚洲AV无码成人精品区蜜桃| 日韩精品无码免费专区午夜不卡| 亚洲av无码天堂一区二区三区 | 中文字幕无码av激情不卡久久 | 无码一区二区三区爆白浆| 无码国产色欲XXXXX视频| 中文有无人妻vs无码人妻激烈| 亚洲精品无码你懂的网站| 国产丰满乱子伦无码专| 国产精品亚洲专区无码牛牛| 人妻少妇看A偷人无码精品| 中文字幕无码成人免费视频| 99精品人妻无码专区在线视频区| 久久精品国产亚洲AV无码偷窥| 日韩精品无码中文字幕一区二区 | 中文字幕乱码无码人妻系列蜜桃 | 亚洲爆乳大丰满无码专区 | 日韩成人无码一区二区三区| 国产精品爽爽V在线观看无码| 色国产色无码色欧美色在线|