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
}
如果我們運行該應用程序,則字段value
和properties
具有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上找到源。