知識庫 / Spring / Spring Cloud RSS 訂閱

Spring Cloud Consul 快速指南

Spring Cloud
HongKong
5
02:12 PM · Dec 06 ,2025

1. 概述

Spring Cloud Consul 項目提供與 Spring Boot 應用程序的便捷集成,利用 Consul。

Consul 是一個提供用於解決微服務架構中一些常見挑戰的組件的工具:

  • 服務發現 – 自動註冊和註銷服務實例的網絡位置
  • 健康檢查 – 檢測服務實例是否處於運行狀態
  • 分佈式配置 – 確保所有服務實例使用相同的配置

在本文中,我們將瞭解如何配置 Spring Boot 應用程序以使用這些功能。

2. 先決條件

首先,建議您快速瞭解 Consul及其所有功能。

在本文中,我們將使用運行在 localhost:8500 的 Consul 代理。有關如何安裝 Consul 並運行代理的更多詳細信息,請參閲此 鏈接

首先,我們需要將 spring-cloud-starter-consul-all 依賴項添加到我們的 pom.xml 中:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-consul-all</artifactId>
    <version>3.1.1</version>
</dependency>

3. 服務發現

讓我們編寫我們的第一個 Spring Boot 應用程序,並與正在運行的 Consul 代理進行集成:

@SpringBootApplication
public class ServiceDiscoveryApplication {

    public static void main(String[] args) {
        new SpringApplicationBuilder(ServiceDiscoveryApplication.class)
          .web(true).run(args);
    }
}

默認情況下,Spring Boot 會嘗試連接到 Consul 代理,地址為 localhost:8500. 要使用其他設置,需要更新 application.yml 文件:

spring:
  cloud:
    consul:
      host: localhost
      port: 8500

然後,如果我們在瀏覽器中訪問 Consul 代理的站點,地址為 http://localhost:8500,我們會看到我們的應用程序已正確地在 Consul 中註冊,標識符來自 “${spring.application.name}:${profiles separated by comma}:${server.port}”

為了自定義此標識符,我們需要更新屬性 spring.cloud.discovery.instanceId 為另一個表達式:

spring:
  application:
    name: myApp
  cloud:
    consul:
      discovery:
        instanceId: ${spring.application.name}:${random.value}

如果再次運行該應用程序,我們會發現它使用了“MyApp”標識符加上一個隨機值進行註冊。我們需要這樣做,以便在本地機器上運行該應用程序的多個實例。

最後,要禁用服務發現,需要將 spring.cloud.consul.discovery.enabled 屬性設置為 false

3.1. 查詢服務

我們已經在 Consul 中註冊了我們的應用程序,但客户端如何找到服務端點?我們需要一個發現客户端服務,從 Consul 獲取正在運行且可用的服務。

Spring 提供 DiscoveryClient API 用於此目的,我們可以通過使用 @EnableDiscoveryClient 註解啓用它:

@SpringBootApplication
@EnableDiscoveryClient
public class DiscoveryClientApplication {
    // ...
}

然後,我們可以將 DiscoveryClient Bean 注入到我們的控制器中,並訪問其實例:

@RestController
public class DiscoveryClientController {
 
    @Autowired
    private DiscoveryClient discoveryClient;

    public Optional<URI> serviceUrl() {
        return discoveryClient.getInstances("myApp")
          .stream()
          .findFirst() 
          .map(si -> si.getUri());
    }
}

最後,我們將定義應用程序的端點:

@GetMapping("/discoveryClient")
public String discoveryPing() throws RestClientException, 
  ServiceUnavailableException {
    URI service = serviceUrl()
      .map(s -> s.resolve("/ping"))
      .orElseThrow(ServiceUnavailableException::new);
    return restTemplate.getForEntity(service, String.class)
      .getBody();
}

@GetMapping("/ping")
public String ping() {
    return "pong";
}

“myApp/ping”路徑是Spring應用程序名稱,包含服務端點。Consul將提供所有名為myApp的應用程序。

4. 健康檢查

Consul 定期檢查服務端點的健康狀況。

默認情況下,Spring 實現健康端點,如果應用程序正常運行,則返回 200 OK 如果需要自定義端點,則必須更新 application.yml

spring:
  cloud:
    consul:
      discovery:
        healthCheckPath: /my-health-check
        healthCheckInterval: 20s

因此,Consul 將每 20 秒對 “/my-health-check” 端點進行輪詢。

讓我們定義我們的自定義健康檢查服務,以返回 FORBIDDEN 狀態:

@GetMapping("/my-health-check")
public ResponseEntity<String> myCustomCheck() {
    String message = "Testing my healh check function";
    return new ResponseEntity<>(message, HttpStatus.FORBIDDEN);
}

如果我們訪問 Consul 代理站點,我們會發現我們的應用程序正在失敗。為了解決這個問題,“/my-health-check” 服務應該返回 HTTP 200 OK 狀態碼。

5. 分佈式配置

此功能允許在所有服務之間同步配置

Consul 會監視任何配置更改,然後觸發所有服務的更新。

首先,我們需要在我們的 pom.xml 中添加 spring-cloud-starter-consul-config 依賴項:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-consul-config</artifactId>
    <version>3.1.1</version>
</dependency>

我們還需要將 Consul 和 Spring 應用名稱的設置從 application.yml 文件移動到 bootstrap.yml 文件中,因為 Spring 會首先加載 bootstrap.yml 文件。

然後,我們需要啓用 Spring Cloud Consul Config:

spring:
  application:
    name: myApp
  cloud:
    consul:
      host: localhost
      port: 8500
      config:
        enabled: true

Spring Cloud Consul Config 將在 Consul 中查找屬性,路徑為 “/config/myApp”。如果有一個名為 “my.prop” 的屬性,則需要在 Consul 代理站點創建該屬性。

可以通過前往 “KEY/VALUE” 部分,然後輸入 “/config/myApp/my/prop”“Create Key” 表單中,以及 “Hello World” 作為值,即可創建屬性。最後,點擊 “Create” 按鈕。

請注意,如果我們在使用 Spring 配置文件,則需要將配置文件名稱附加到 Spring 應用名稱後。例如,如果我們在使用 “dev” 配置文件,則 Consul 路徑最終將為 “/config/myApp,dev”

現在,讓我們看看包含注入屬性的控制器是什麼樣子的:

@RestController
public class DistributedPropertiesController {

    @Value("${my.prop}")
    String value;

    @Autowired
    private MyProperties properties;

    @GetMapping("/getConfigFromValue")
    public String getConfigFromValue() {
        return value;
    }

    @GetMapping("/getConfigFromProperty")
    public String getConfigFromProperty() {
        return properties.getProp();
    }
}

以及 MyProperties 類:

@RefreshScope
@Configuration
@ConfigurationProperties("my")
public class MyProperties {
    private String prop;

    // standard getter, setter
}

如果運行該應用程序,字段 valueproperties 均具有與 Consul 相同的 值。

5.1. 更新配置

如果沒有重啓 Spring Boot 應用程序,如何更新配置呢?

如果返回到 Consul 代理站點,並更新屬性“/config/myApp/my/prop”為另一個值,例如“New Hello World”,則字段“value”不會發生變化,字段“properties”將被更新為“New Hello World”,正如預期的那樣。

這是因為字段“properties”是一個 MyProperties 類,具有 @RefreshScope 註解。所有帶有 @RefreshScope 註解的 Bean 在配置更改後都會被刷新。

在實際應用中,我們不應該在 Consul 中直接存儲屬性,而是應該將它們持久地存儲在其他地方。我們可以使用 Config Server 來實現這一點。

6. 結論

在本文中,我們學習瞭如何配置 Spring Boot 應用程序,以便與 Consul 進行服務發現,自定義健康檢查規則並共享分佈式配置。

我們還介紹了客户端調用這些註冊服務的一系列方法。

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

發佈 評論

Some HTML is okay.