Spring Cloud Consul快速指南

1.概述

Spring Cloud Consul項目可輕鬆與Consul集成以用於Spring Boot應用程序。

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>1.3.0.RELEASE</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將嘗試通過localhost:8500連接到Consul代理。要使用其他設置,我們需要更新application.yml文件:

spring:

 cloud:

 consul:

 host: localhost

 port: 8500

然後,如果我們在瀏覽器中通過http://localhost:8500訪問Consul代理的站點,則會看到我們的應用程序已在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應用程序名稱。領事將提供名為“myApp”.所有可用應用程序“myApp”.

4.健康檢查

領事定期檢查服務端點的運行狀況。

默認情況下,如果應用程序啟動Spring會實現運行狀況端點以返回200 OK 。如果要自定義端點,則必須更新application.yml:

spring:

 cloud:

 consul:

 discovery:

 healthCheckPath: /my-health-check

 healthCheckInterval: 20s

結果,領事將每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將監視任何配置更改,然後觸發所有服務的更新。

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

<dependency>

 <groupId>org.springframework.cloud</groupId>

 <artifactId>spring-cloud-starter-consul-config</artifactId>

 <version>1.3.0.RELEASE</version>

 </dependency>

我們還需要將Consul和Spring應用程序名稱的設置從application.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”部分,然後在“Create Key”表單中輸入“/config/myApp/my/prop” ,並將“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中相同的“Hello World”值。

5.1。更新配置

如何在不重新啟動Spring Boot應用程序的情況下更新配置?

如果我們返回領事代理站點,並使用另一個值(例如“New Hello World”更新屬性“/config/myApp/my/prop” “New Hello World” ,則字段value將不會更改,並且字段properties將更新為如預期的那樣, “New Hello World”

這是因為字段properties是具有@RefreshScope批註的MyProperties類。配置更改後,所有帶有@RefreshScope註釋的@RefreshScope將被刷新。

在現實生活中,我們不應該直接在Consul中擁有這些屬性,而應該將其永久存儲在某個地方。我們可以使用配置服務器來做到這一點。

六,結論

在本文中,我們已經看到瞭如何設置Spring Boot應用程序以與Consul一起使用以實現Service Discovery,如何自定義運行狀況檢查規則以及共享分佈式配置。

我們還為客戶端引入了許多方法來調用這些註冊的服務。

與往常一樣,可以在GitHub上找到源。