国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

強悍的重試機制:Spring Boot 中 WebClient 彈性設計實戰

開發 前端
Spring WebFlux 包含一個用于執行 HTTP 請求的客戶端。WebClient 具有基于 Reactor 的功能性流暢 API,它可以聲明式地組成異步邏輯,而無需處理線程或并發問題。它是完全無阻塞的,支持流式傳輸。

環境:SpringBoot3.4.2

1. 簡介

Spring WebFlux 包含一個用于執行 HTTP 請求的客戶端。WebClient 具有基于 Reactor 的功能性流暢 API,它可以聲明式地組成異步邏輯,而無需處理線程或并發問題。它是完全無阻塞的,支持流式傳輸。

在分布式系統中,網絡請求可能因臨時故障(如超時、服務不可用、限流)而失敗。合理的重試機制能提升系統韌性,但不同 HTTP 客戶端的實現方式差異顯著。RestTemplate 和 RestClient 都需要通過自定義攔截器(ClientHttpRequestInterceptor)或是借助 Spring Retry 庫實現重試機制,開發者需手動處理異常類型、重試次數、退避策略等細節,代碼冗余且易出錯。而 WebClient 內置了響應式重試機制,通過 retryWhen 操作符與 RetryBackoffSpec 組合,可聲明式地定義重試規則,無需編寫攔截器或引入額外依賴。這種設計不僅簡化了代碼,還天然適配異步非阻塞場景

接下來,我們將詳細的介紹WebClient的重試機制。

2.實戰案例

2.1 基本使用

默認情況下,WebClient 實例不會自動執行任何重試操作,除非你主動添加相關操作。當你調用其他服務時,如果發生超時或拋出錯誤,請求會直接失敗,并將錯誤沿響應式鏈(reactive chain)傳遞下去。若要實現重試功能,你需要在數據流中添加一個重試操作符(retry operator)。

最直接的重試方式是使用 .retry(n) 方法,其中 n 表示首次失敗后允許的最大重試次數。如下示例:

// 基本配置
HttpClient httpClient = HttpClient.create()
    .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 2000);
WebClient webClient = WebClient.builder()
    .baseUrl("http://localhost:9999")
    .clientConnector(new ReactorClientHttpConnector(httpClient))
    .build() ;
// 調用遠程調用
webClient.get()
  .uri("/api/query")
  .retrieve()
  .bodyToMono(String.class)
  .doOnError(err -> {
    System.err.printf("發生錯誤: %s%n", err.getMessage()) ;
  })
  .retry(2)
  .subscribe(System.out::println, error -> System.err.printf("請求失敗: %s%n", error.getMessage()));

這種方法添加簡單,但存在一個問題:它會立即連續重試,不給遠程系統任何恢復時間。對于偶發的網絡抖動(network flukes),這種策略可能有效;但如果問題是由服務過載(heavy load)引起的,連續重試反而可能加劇系統壓力。

注意:每次重試都會在前一次請求剛結束時立即啟動。這意味著,如果被調用的服務已經處于高負載狀態,這種連續重試只會進一步加劇系統壓力。總計3次。

圖片圖片

下面是關于retry方法執行原理:

圖片圖片

2.2 重試添加退避規則

重試調用在它們之間留有間隔時效果會更好。再次嘗試前給系統一個短暫的時間。這個間隔可以保持不變,也可以每次逐漸延長。我們可以使用 Retry.backoff 與 retryWhen 結合,這樣能做更多控制權,并且更符合 Reactor 處理重試的方式。并且可以決定暫停多久以及允許嘗試多少次。如下示例:

WebClient webClient = ... ;


webClient.get()
  .uri("/api/query")
  .retrieve()
  .bodyToMono(String.class)
  .doOnError(err -> {
    System.err.printf("發生錯誤: %s - %s%n", DateTimeFormatter.ofPattern("mm:ss")
        .format(LocalDateTime.now()), err.getMessage()) ;
  })
  .retryWhen(Retry.backoff(3, Duration.ofSeconds(1)))
  .subscribe(System.out::println, error -> System.err.printf("請求失敗: %s%n", error.getMessage()));

輸出結果

圖片圖片

首次重試間隔為1s,之后是3s。這也給了目標服務恢復的時間。

2.3 自定義重試機制

并非所有失敗都值得重試。有些錯誤是暫時的,有些則無法自行恢復。例如:

  • 404 表示請求的資源不存在
  • 400 通常表示請求格式錯誤

這類錯誤無需重試,因為重復嘗試只會得到相同結果。但 500 服務器錯誤 或 超時 可能意味著服務只需多一秒即可恢復,此時重試才有意義。

通過 Retry 構建器,你可以配置一個過濾器,明確指定哪些失敗需要重試、哪些應直接跳過。如下示例:

Retry retryStrategy = Retry.fixedDelay(2, Duration.ofMillis(500))
  // 過濾,值對500以上的錯誤碼進行重試
  .filter(throwable -> {
    if (throwable instanceof WebClientResponseException) {
      int status = ((WebClientResponseException) throwable).getStatusCode().value() ;
      return status >= 500;
    }
    return throwable instanceof WebClientRequestException;
  }) ;


webClient.get()
  .uri("/api/query")
  .retrieve()
  .bodyToMono(String.class)
  .doOnError(err -> {
    System.err.printf("發生錯誤: %s - %s%n", DateTimeFormatter.ofPattern("mm:ss")
        .format(LocalDateTime.now()), err.getMessage()) ;
  })
  .retryWhen(retryStrategy)
  .subscribe(System.out::println, error -> System.err.printf("請求失敗: %s%n", error.getMessage()));

當發生小于500錯誤時,輸出如下:

圖片圖片

當發生大于等于500錯誤時,輸出如下:

圖片圖片

2.4 避免重試風暴

重試機制若使用不當易引發 "重試風暴":當大量服務無延遲地連續重試失敗請求時,會向已承壓的下游系統爆發式涌入流量,導致其崩潰并擴散至整個系統。避免風暴的關鍵在于退避(Backoff)與抖動(Jitter):退避通過逐步延長重試間隔降低負載,抖動則引入隨機性防止請求周期性對齊。如下示例:

Retry retryWithJitter = Retry.backoff(4, Duration.ofMillis(500))
    .jitter(0.8)
    .filter(throwable -> {
      if (throwable instanceof WebClientResponseException) {
        int status = ((WebClientResponseException) throwable).getStatusCode().value() ;
        return status >= 500;
      }
      return throwable instanceof WebClientRequestException;
    }) ;
webClient.get()
  .uri("/api/query")
  .retrieve()
  .bodyToMono(String.class)
  .doOnError(err -> {
    System.err.printf("發生錯誤: %s - %s%n", DateTimeFormatter.ofPattern("mm:ss")
        .format(LocalDateTime.now()), err.getMessage()) ;
  })
  .retryWhen(retryWithJitter)
  .subscribe(System.out::println, error -> System.err.printf("請求失敗: %s%n", error.getMessage()));

輸出結果

圖片圖片

此處設置的抖動范圍為 80%,即每次重試的延遲時間會在基準值基礎上隨機增減一定比例。這種微小的時序偏移能避免所有重試請求在同一時刻集中涌向后端系統。

2.5 重試最終兜底 - 熔斷

當重試徹底失效時,需立即停止請求以避免系統雪崩,此時熔斷器(Circuit Breaker)便派上用場。它會持續監測失敗次數,一旦達到閾值,便臨時阻斷新請求,為下游服務爭取恢復時間。

Spring Boot 的 WebClient 本身未內置熔斷功能,但可無縫集成 Spring Cloud Circuit Breaker 或 Resilience4j。通過熔斷器包裝 WebClient 邏輯,可在故障持續時提前攔截請求,防止其涌向已崩潰的下游系統。如下示例:

首先,引入依賴
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-circuitbreaker-resilience4j</artifactId>
  <version>3.3.0</version>
</dependency>

配置文件

resilience4j:
  circuitbreaker:
    # 此種方式適用于使用CircuitBreakerFactory方式
    configs:
      order-service:
        minimum-number-of-calls: 1
        failure-rate-threshold: 10
        wait-duration-in-open-state: 10s

示例代碼

private final ReactiveCircuitBreakerFactory<?, ?> rcbFactory ;


public Mono<String> invoke() {
  return this.rcbFactory.create("order-service").run(webClient.get()
    .uri("/api/query")
    .retrieve()
    .bodyToMono(String.class)
    .doOnError(err -> {
      System.err.printf("發生錯誤: %s - %s%n", DateTimeFormatter.ofPattern("mm:ss")
          .format(LocalDateTime.now()), err.getMessage()) ;
    }), ex -> Mono.just("fallback response")) ;
}

運行結果

圖片圖片

責任編輯:武曉燕 來源: Springboot全家桶實戰案例
相關推薦

2021-02-20 10:02:22

Spring重試機制Java

2022-05-06 07:44:10

微服務系統設計重試機制

2025-02-26 10:49:14

2022-11-14 08:19:59

重試機制Kafka

2025-04-18 03:00:00

2025-09-10 07:15:45

2024-09-25 08:32:05

2024-01-04 18:01:55

高并發SpringBoot

2024-11-21 14:42:31

2020-07-19 15:39:37

Python開發工具

2023-10-27 08:20:12

springboot微服務

2025-01-03 08:44:37

kafka消息發送策略

2017-06-16 15:16:15

2017-07-02 16:50:21

2025-12-03 00:57:00

2025-11-10 07:46:24

2025-09-01 07:40:59

2023-11-27 07:44:59

RabbitMQ機制

2023-11-06 08:00:38

接口高可用機制

2025-02-26 08:10:40

點贊
收藏

51CTO技術棧公眾號

国产精品自拍一区| 免费观看日韩电影| 3atv在线一区二区三区| 青青草视频在线免费播放| 久久动漫网址| 欧美一区二区三区在线| 1区不卡电影| 国产精品系列在线观看| 成人免费视频视频在| 国产精品22p| 精品福利av导航| 超碰在线公开超碰在线| 95精品视频在线| 亚洲欧洲一区二区| 欧美色图首页| 国产成人精品免费久久久久| 亚洲伦乱视频| 欧美大片日本大片免费观看| 欧美日韩视频精品二区| 中文字幕一区二区5566日韩| 国产一线二线三线女| 日韩电影一区二区三区四区| 成人激情直播| 999久久久91| 国产成人高清激情视频在线观看| 国产亚洲字幕| 在线精品国产成人综合| 懂色av一区| 欧美一级高清片| 在线观看h片| 欧美午夜片欧美片在线观看| 国产美女免费观看| 中文字幕亚洲在| 国产精品自拍视频在线| 91在线视频免费观看| 无码人妻少妇伦在线电影| 国内精品第一页| 四虎永久国产精品| 免费国产自线拍一欧美视频| 国产精品麻豆免费版| 国产精品久久久久久麻豆一区软件 | 黑人中文字幕一区二区三区| 国产一区二区三区日韩精品| 热久久美女精品天天吊色| 青青久久av| 国产精品第二页| 日韩av密桃| 国产日韩精品久久| 国产日韩一区二区三区在线| 日本婷婷久久久久久久久一区二区 | 日本一区二区三区四区视频| 一本久久青青| 国产精品视频午夜| 亚洲高清资源在线观看| 成人91视频| 国产色综合网| 丰满女人性猛交| 成人av中文字幕| 天天爽人人爽夜夜爽| 亚洲伦在线观看| 在线免费福利| 在线91免费看| 成人国产二区| 久久久久久久97| 日韩欧美中文| 奇米精品在线| 91丨porny丨中文| 日本韩国福利视频| 欧美体内she精视频| 蜜桃传媒在线观看免费进入 | 一区二区三区黄色| 一区二区三区国产好| 国产日本欧美一区二区三区在线| 亚洲国产日韩在线| 日韩成人手机在线| 亚洲激情综合网| 久草在线资源网站| 中国黄色录像片| 国产成人午夜视频| 黄色片视频在线| 色婷婷国产精品| 天堂在线中文网官网| 久久久久久国产精品久久| 在线成人激情| 国产a级片免费看| 国产精品福利av| 在线免费av网站| 久久精品久久久久久| 欧美日韩一二| 亚洲巨乳在线观看| 亚洲色图视频免费播放| 免费大片在线观看www| 中文日韩在线观看| 国产精品88久久久久久| 日韩中文在线字幕| 午夜av区久久| 99久久婷婷国产综合精品首页 | 视频在线不卡| 亚洲国产精品成人精品| 欧美午夜18电影| 激情五月综合色婷婷一区二区| 国产xxx精品视频大全| 中文字幕在线一二| 最新69国产成人精品视频免费| 色狮一区二区三区四区视频| 99视频精品全部免费看| 天天爽夜夜爽夜夜爽精品视频| 老司机深夜福利在线观看| 国产精品人成电影在线观看| 国产一区二区精品久久99| 羞羞视频在线观看| 视频一区二区三区在线看免费看| 少妇一晚三次一区二区三区| 中文字幕在线免费不卡| 日本在线免费观看视频| 亚洲毛片在线免费观看| 91综合久久| 日韩精品一区二区三区丰满 | 黄在线观看网站| 欧美丰满少妇xxxxx| 国产精品色哟哟| 欧美日韩一区二区三区在线电影 | 国产日韩亚洲精品| 精品日韩成人av| 国产v综合v亚洲欧| 日韩电影在线视频| 亚洲精品国模| 精品欧美视频| 麻豆国产一区| 有码在线播放| 丰满少妇被猛烈进入高清播放| 农村妇女精品一二区| 成人信息集中地欧美| 国产精品成人一区| 国产丝袜一区二区| 性做久久久久久免费观看欧美| 26uuu另类欧美亚洲曰本| 麻豆精品视频在线观看视频| 国产影视一区| 爽爽窝窝午夜精品一区二区| 国产成人夜色高潮福利影视| 成入视频在线观看| 成人18在线| a毛片在线播放| 国产精品999视频| 免费在线亚洲| 女人天堂在线| 亚洲a中文字幕| 亚洲1区2区3区4区| 日韩a级大片| 中文字幕网av| 欧美成人免费网| 成人av在线影院| 成人在线黄色| 四虎4hu永久免费入口| 亚洲第一精品夜夜躁人人躁| 日本成人超碰在线观看| 国产盗摄一区二区| 一区二区三区四区免费观看| 国产丝袜一区二区三区| 精品无人区卡一卡二卡三乱码免费卡| 天堂亚洲精品| 99亚洲精品视频| 怡红院精品视频| 97精品视频在线观看自产线路二| 婷婷精品久久久久久久久久不卡| 国产婷婷一区二区三区| www.日韩视频| 国产精品伦理在线| 欧美理论在线播放| 在线观看av中文| 国产一区精品在线| 精品日韩一区二区三区免费视频| 精品中文字幕一区二区| 日韩免费福利视频| 激情婷婷综合网| 国产成人av在线| 日本二三区不卡| 亚洲永久免费精品| 日韩伦理在线一区| 激情内射人妻1区2区3区| 欧美专区国产专区| 日韩欧美在线国产| 青青草国产精品亚洲专区无| 久久久成人av毛片免费观看| 色片在线免费观看| 91视频国产高清| 精品日韩欧美一区二区| va亚洲va日韩不卡在线观看| 久久男人av| 97在线观看免费观看高清| 潘金莲一级淫片aaaaaa播放1| 久久成年人免费电影| 香蕉久久一区二区不卡无毒影院| 亚洲九九精品| 久久免费影院| 亚洲女人天堂在线| www.-级毛片线天内射视视| 97视频在线播放| 制服丝袜亚洲色图|