知識庫 / Spring / Spring Cloud RSS 訂閱

Spring Cloud 熔斷器快速指南

Spring Cloud
HongKong
5
01:01 PM · Dec 06 ,2025

1. 概述

在本教程中,我們將介紹 Spring Cloud Circuit Breaker 項目,並學習如何利用它。

首先,我們將瞭解 Spring Cloud Circuit Breaker 提供的附加功能,以及它與現有斷路器實現的區別。 接下來,我們將學習如何使用 Spring Boot 自定義配置機制,將一個或多個斷路器集成到我們的應用程序中。

請注意,關於斷路器及其工作原理,您可以在《Hystrix 簡介》、《Spring Cloud Netflix Hystrix》和《Resilience4j 指南》中找到更多信息。

2. Spring Cloud 熔斷器

在最近之前,Spring Cloud 僅提供了一種在應用程序中添加熔斷器的方式,即通過使用 Netflix Hystrix,作為 Spring Cloud Netflix 項目的一部分。

Spring Cloud Netflix 項目實際上只是圍繞 Hystrix 的註解驅動的包裝庫。因此,這兩個庫是緊密耦合的。這意味着我們不能在不更改應用程序的情況下切換到另一種熔斷器實現。

Spring Cloud Circuit Breaker 項目解決了這個問題。它提供了一個跨不同熔斷器實現抽象層。它具有可插拔的架構,因此我們可以針對提供的抽象/接口進行編碼,並根據我們的需求切換到另一種實現。

對於我們的示例,我們將僅關注 Resilience4J 實現。 但是,這些技術可用於其他插件。

3. 自動配置

為了在我們的應用程序中使用特定的斷路器實現,我們需要添加相應的 Spring starter。 在我們的例子中,我們使用 spring-cloud-starter-circuitbreaker-resilience4j

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-circuitbreaker-resilience4j</artifactId>
    <version>1.0.2.RELEASE</version>
</dependency>

自動配置機制會在 classpath 中發現任何一個啓動器時,配置所需的斷路器 Bean。

如果想要禁用 Resilience4J 的自動配置,可以將其 spring.cloud.circuitbreaker.resilience4j.enabled 屬性設置為 false

4. 一個簡單的電路斷路器示例

讓我們使用 Spring Boot 創建一個 Web 應用程序,以探索 Spring Cloud Circuit Breaker 庫的工作原理。

我們將構建一個簡單的 Web 服務,該服務返回專輯列表。 假設原始列表由第三方服務提供。 為了簡化起見,我們將使用 Jsonplaceholder 提供的外部模擬 API 來檢索列表:

https://jsonplaceholder.typicode.com/albums

4.1. 創建斷路器

讓我們創建一個斷路器。首先,我們通過注入 CircuitBreakerFactory 實例來開始:

@Service
public class AlbumService {
    
    @Autowired
    private CircuitBreakerFactory circuitBreakerFactory;

    //... 

}

現在,我們可以輕鬆地使用 CircuitBreakerFactory#create方法創建斷路器。它接受斷路器標識符作為參數:

CircuitBreaker circuitBreaker = circuitBreakerFactory.create("circuitbreaker");

4.2. 將任務封裝在斷路器中

為了將任務封裝並使用斷路器保護,我們需要調用 run 方法,該方法接受一個 <em ref="supplier" /> 作為參數。

public String getAlbumList() {
    CircuitBreaker circuitBreaker = circuitBreakerFactory.create("circuitbreaker");
    String url = "https://jsonplaceholder.typicode.com/albums";

    return circuitBreaker.run(() -> restTemplate.getForObject(url, String.class));
}

斷路器會運行我們的方法並提供容錯機制。

有時,我們的外部服務可能響應時間過長、拋出意外異常或外部服務或主機不存在。在這種情況下,我們可以將 備用方案 作為 run 方法的第二個參數提供:

public String getAlbumList() {
    CircuitBreaker circuitBreaker = circuitBreakerFactory.create("circuitbreaker");
    String url = "http://localhost:1234/not-real";
    
    return circuitBreaker.run(() -> restTemplate.getForObject(url, String.class), 
      throwable -> getDefaultAlbumList());
}

用於回退的 lambda 接收 Throwable 作為輸入,描述錯誤信息。這意味着 我們可以根據觸發回退的異常類型,向調用者提供不同的回退結果

在這種情況下,我們不會考慮異常,只會返回緩存的專輯列表。

如果外部調用以異常結束且沒有提供回退,則 Spring 會拋出 NoFallbackAvailableException

4.3. 構建控制器

現在,讓我們完成我們的示例並創建一個簡單的控制器,該控制器調用服務方法並通過瀏覽器呈現結果:

@RestController
public class Controller {

    @Autowired
    private Service service;

    @GetMapping("/albums")
    public String albums() {
        return service.getAlbumList();
    }

}

最後,讓我們調用 REST 服務並查看結果:

[GET] http://localhost:8080/albums

5. 全局自定義配置

通常情況下,默認配置無法滿足需求。因此,我們需要根據我們的用例創建具有自定義配置的斷路器。

為了覆蓋默認配置,我們需要在 <em @Configuration</em> 類中指定自己的 Bean 和屬性。

在這裏,我們將為所有斷路器定義一個全局配置。為此,我們需要定義一個 <em Customizer&lt;CircuitBreakerFactory&gt;</em > Bean</strong>。 讓我們使用<em Resilience4JCircuitBreakerFactory` 實現。

首先,我們將根據 Resilience4j 教程,定義斷路器和時間限制器配置類:

CircuitBreakerConfig circuitBreakerConfig = CircuitBreakerConfig.custom()
  .failureRateThreshold(50)
  .waitDurationInOpenState(Duration.ofMillis(1000))
  .slidingWindowSize(2)
  .build();
TimeLimiterConfig timeLimiterConfig = TimeLimiterConfig.custom()
  .timeoutDuration(Duration.ofSeconds(4))
  .build();

接下來,我們通過使用 Resilience4JCircuitBreakerFactory.configureDefault 方法,將配置嵌入到 Customizer Bean 中:

@Configuration
public class Resilience4JConfiguration {
    @Bean
    public Customizer<Resilience4JCircuitBreakerFactory> globalCustomConfiguration() {
        
        // the circuitBreakerConfig and timeLimiterConfig objects

        return factory -> factory.configureDefault(id -> new Resilience4JConfigBuilder(id)
          .timeLimiterConfig(timeLimiterConfig)
          .circuitBreakerConfig(circuitBreakerConfig)
          .build());
    } 
}

6. 詳細自定義配置

當然,我們的應用程序可以擁有多個斷路器。因此,在某些情況下,我們需要為每個斷路器提供特定的配置。

同樣,我們可以定義一個或多個 自定義器 (Customizer) Bean。然後,我們可以使用 Resilience4JCircuitBreakerFactory.configure 方法為每個 Bean 提供不同的配置:

@Bean
public Customizer<Resilience4JCircuitBreakerFactory> specificCustomConfiguration1() {

    // the circuitBreakerConfig and timeLimiterConfig objects

    return factory -> factory.configure(builder -> builder.circuitBreakerConfig(circuitBreakerConfig)
      .timeLimiterConfig(timeLimiterConfig).build(), "circuitBreaker");
}

在這裏,我們提供第二個參數,即配置的斷路器 ID。

通過向同一個方法提供斷路器 ID 列表,也可以配置多個具有相同配置的斷路器。

@Bean
public Customizer<Resilience4JCircuitBreakerFactory> specificCustomConfiguration2() {

    // the circuitBreakerConfig and timeLimiterConfig objects

    return factory -> factory.configure(builder -> builder.circuitBreakerConfig(circuitBreakerConfig)
      .timeLimiterConfig(timeLimiterConfig).build(),
        "circuitBreaker1", "circuitBreaker2", "circuitBreaker3");
}

7. 替代實現

我們已經瞭解瞭如何使用 Resilience4j 實現來創建或多個斷路器,並結合 Spring Cloud Circuit Breaker 使用。

然而,Spring Cloud Circuit Breaker 還支持其他實現,我們可以將其應用於我們的應用程序:

值得注意的是,我們可以將不同的斷路器實現混合使用 在我們的應用程序中。我們並不侷限於使用一個庫。

上述庫的功能遠不止我們在這裏所探討的。但是,Spring Cloud Circuit Breaker 只是對斷路器部分進行抽象。例如,Resilience4j 還提供了 RateLimiter、Bulkhead、Retry 等模塊,除了本文中使用的 CircuitBreaker 和 TimeLimiter 模塊之外。

8. 結論

在本文中,我們探索了 Spring Cloud Circuit Breaker 項目。

首先,我們瞭解了 Spring Cloud Circuit Breaker 的概念,以及它如何允許我們在應用程序中添加斷路器。

接下來,我們利用 Spring Boot 的自動配置機制,演示瞭如何定義和集成斷路器。 此外,我們通過一個簡單的 REST 服務展示了 Spring Cloud Circuit Breaker 的工作原理。

最後,我們學習瞭如何配置所有斷路器,包括整體配置和單獨配置。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.