Перейти к основному содержимому

Краткое руководство по Spring Cloud Consul

· 6 мин. чтения

1. Обзор

Проект Spring Cloud Consul обеспечивает простую интеграцию с Consul для приложений Spring Boot.

Consul — это инструмент, который предоставляет компоненты для решения некоторых наиболее распространенных проблем в архитектуре микросервисов:

  • Обнаружение службы — для автоматической регистрации и отмены регистрации сетевых расположений экземпляров службы.
  • Проверка работоспособности — чтобы определить, когда экземпляр службы запущен и работает.
  • Распределенная конфигурация — чтобы все экземпляры службы использовали одну и ту же конфигурацию.

В этой статье мы увидим, как мы можем настроить приложение Spring Boot для использования этих функций.

2. Предпосылки

Для начала рекомендуется бегло взглянуть на Consul и все его возможности.

В этой статье мы будем использовать агент Consul, работающий на localhost:8500 . Подробнее о том, как установить 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

Затем, если мы зайдем на сайт агента Консула в браузере по адресу http://localhost:8500 , мы увидим, что наше приложение было правильно зарегистрировано в Консуле с идентификатором из «${spring.application.name}:${profiles через запятую}:${server.port}» .

Чтобы настроить этот идентификатор, нам нужно обновить свойство spring.cloud.discovery.instanceId другим выражением:

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

Если мы снова запустим приложение, мы увидим, что оно было зарегистрировано с использованием идентификатора «MyApp» плюс случайное значение. Нам это нужно для запуска нескольких экземпляров нашего приложения на нашей локальной машине.

Наконец, чтобы отключить Service Discovery, нам нужно установить для свойства spring.cloud.consul.discovery.enabled значение false .

3.1. Поиск услуг

Наше приложение уже зарегистрировано в Consul, но как клиенты могут найти конечные точки сервиса? Нам нужна клиентская служба обнаружения, чтобы получить работающую и доступную службу от Consul.

Spring предоставляет API DiscoveryClient для этого , который мы можем включить с помощью аннотации @EnableDiscoveryClient :

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

Затем мы можем внедрить bean- компонент DiscoveryClient в наш контроллер и получить доступ к экземплярам:

@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 будет опрашивать конечную точку «/my-health-check» каждые 20 секунд.

Давайте определим нашу пользовательскую службу проверки работоспособности, чтобы она возвращала статус ЗАПРЕЩЕНО :

@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>3.1.1</version>
</dependency>

Нам также нужно переместить настройки имени приложения Consul и Spring из файла application.yml в файл bootstrap.yml , который Spring загружает первым.

Затем нам нужно включить 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» в качестве значения. Наконец, нажмите кнопку «Создать» .

Имейте в виду, что если мы используем профили 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
}

Если мы запустим приложение, значение поля и свойства будут иметь то же значение «Hello World» из Consul.

5.1. Обновление конфигурации

Как насчет обновления конфигурации без перезапуска приложения Spring Boot?

Если мы вернемся на сайт агента Consul и обновим свойство «/config/myApp/my/prop» другим значением, например «New Hello World» , то значение поля не изменится, а свойства поля будут обновлены до «Новый Hello World» , как и ожидалось.

Это связано с тем, что свойства поля — это класс MyProperties , имеющий аннотацию @RefreshScope . Все bean-компоненты, аннотированные аннотацией @RefreshScope , будут обновлены после изменения конфигурации.

В реальной жизни у нас не должно быть свойств прямо в Консуле, но мы должны постоянно их где-то хранить. Мы можем сделать это с помощью сервера конфигурации .

6. Заключение

В этой статье мы увидели, как настроить наши приложения Spring Boot для работы с Consul для целей обнаружения служб, настроить правила проверки работоспособности и поделиться распределенной конфигурацией.

Мы также представили ряд подходов, позволяющих клиентам вызывать эти зарегистрированные службы.

Как обычно, исходники можно найти на GitHub .