Spring Cloud Consul 基礎使用介紹

1.概述

Consul 是 HashiCorp 公司推出的開源工具,用於實現分佈式系統的服務發現與配置。與其他分佈式服務註冊與發現的方案,Consul的方案更“一站式”,內置了服務註冊與發現框 架、分佈一致性協議實現、健康檢查、Key/Value存儲、多數據中心方案,不再需要依賴其他工具(比如ZooKeeper等)。

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

  • 服務發現 - 自動註冊和取消註冊服務實例的網絡位置
  • 運行狀況檢查 - 檢測服務實例何時啓動並運行
  • 分佈式配置 - 確保所有服務實例使用相同的配置

Spring Cloud Consul 項目提供Spring Boot 集成 Consul的非常輕鬆的方法。在本文中,我們將瞭解如何配置Spring Boot應用程序來使用Consul。

2.先決條件

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

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

在windows下安裝Consul,
去官網下載:https://www.consul.io/downloads.html

解壓到某個目錄下。cmd啓動:

consul agent -dev

3.引入依賴

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

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

4.服務發現

4.1 服務註冊

讓我們編寫我們的第一個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:
  application:
    name: myApp
  cloud:
    consul:
      host: localhost
      port: 8500

然後,我們在瀏覽器 http://localhost:8500 訪問Consul代理的站點,我們將看到我們的應用程序在Consul中正確註冊。

要想自定義顯示的標識符,我們需要使用另一個表達式更新屬性spring.cloud.discovery.instanceId:

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

如果我們再次運行此應用程序,我們將看到它是使用標識符“MyApp”加上隨機值註冊的。使用random.value是想在本地機器上運行應用程序的多個實例。

如果想要禁用Service Discovery,我們可以將屬性spring.cloud.consul.discovery.enabled設置爲false。

4.2 尋找服務

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

Spring 爲此提供了DiscoveryClient API,我們可以使用@EnableDiscoveryClient註釋啓用它:

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

然後,我們可以將DiscoveryClient bean注入到我們的controller控制器:

@RestController
public class DiscoveryClientController {
  
    @Autowired
    private DiscoveryClient discoveryClient;
 
    public Optional<URI> serviceUrl() {
        return discoveryClient.getInstances("myApp")
          .stream()
          .map(si -> si.getUri());
          .findFirst()
    }
}

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

@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 "Client ping";
}

其中“myApp/ping”的路徑是Spring應用程序的名稱與服務端點。Consul將提供名爲“myApp”的所有可用應用程序。

5.健康檢查

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狀態代碼。

Consul代理網站截圖


健康檢測詳情


6.分佈式配置

此功能允許在所有服務之間同步配置。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: myPro
  cloud:
    consul:
      host: localhost
      port: 8500
      config:
        enabled: true
server:
  port: 8509

Spring Cloud Consul Config將在“/config/myPro”中查找Consul中的屬性。因此,如果我們有一個名爲“my.prop”的屬性,我們需要在Consul代理站點中創建此屬性。

我們可以通過訪問“KEY/VALUE”界面來創建屬性,然後在“Create Key”表單中輸入“/config/myPro/my/prop”,填入“Hello World”作爲值。最後保存此值。

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

@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;

    public String getProp() {
        return prop;
    }

    public void setProp(String prop) {
        this.prop = prop;
    }
}

如果我們運行應用程序,則通過字段值和屬性來取值都會獲得“Hello World”值。

6.1 更新配置

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

我們返回Consul代理站點並使用“New Hello World”更新屬性“/config/myPro/my/prop ”,而其他不變。則字段屬性將更新爲預期的那樣:“New Hello World”。

這是因爲字段屬性是MyProperties類具有@RefreshScope註釋。使用@RefreshScope註釋註釋的所有bean 將在配置更改後刷新。

在實際應用場景中我們不應該直接在Consul中設置屬性,我們應該將它們永久存儲在某個地方。我們可以使用一個Config Server來完成此操作。

7. 結論

在本文中,我們已經瞭解瞭如何設置Spring Boot應用程序以與Consul一起使用以進行服務發現,自定義運行狀況檢查規則和共享分佈式配置。

像往常一樣,可以在GitHub上找到消息來源。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章