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

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

1. обзор

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

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

  • Обнаружение службы - для автоматической регистрации и отмены регистрации сетевых местоположений экземпляров службы

  • Проверка работоспособности - обнаружение, когда экземпляр службы запущен и работает

  • Распределенная конфигурация - чтобы гарантировать, что все экземпляры службы используют одну и ту же конфигурацию

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

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

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

В этой статье мы собираемся использовать агента Consul, работающего наlocalhost:8500. Для получения дополнительных сведений о том, как установить Consul и запустить агент, см. Этотlink.

Во-первых, нам нужно добавить зависимостьspring-cloud-starter-consul-all к нашемуpom.xml:


    org.springframework.cloud
    spring-cloud-starter-consul-all
    1.3.0.RELEASE

3. Сервис Discovery

Давайте напишем наше первое приложение Spring Boot и подключимся к работающему агенту Consul:

@SpringBootApplication
public class ServiceDiscoveryApplication {

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

By default, Spring Boot will try to connect to the Consul agent at 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” плюс случайное значение. Это необходимо для запуска нескольких экземпляров приложения на нашей локальной машине.

Наконец,to disable Service Discovery, we need to set the property spring.cloud.consul.discovery.enabled to false.

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

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

Spring provides a DiscoveryClient API for this, который мы можем включить с помощью аннотации@EnableDiscoveryClient:

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

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

@RestController
public class DiscoveryClientController {

    @Autowired
    private DiscoveryClient discoveryClient;

    public Optional 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 "pong";
}

Путь“myApp/ping” - это имя приложения Spring с конечной точкой службы. Consul предоставит все доступные приложения с именем“myApp”.

4. Проверка здоровья

Консул периодически проверяет состояние конечных точек обслуживания.

По умолчаниюSpring implements the health endpoint to return 200 OK if the app is up. Если мы хотим настроить конечную точку, мы должны обновитьapplication.yml:

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

В результате Consul будет опрашивать конечную точку“/my-health-check” каждые 20 секунд.

Давайте определим нашу настраиваемую службу проверки работоспособности, которая будет возвращать статусFORBIDDEN:

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

Если мы зайдем на сайт агента Consul, мы увидим, что наше приложение не работает. Чтобы исправить это, служба“/my-health-check” должна вернуть код состояния HTTP200 OK.

5. Распределенная конфигурация

Эта функцияallows synchronizing the configuration among all the services. Консул будет следить за любыми изменениями конфигурации и затем запускать обновление всех служб.

Во-первых, нам нужно добавить зависимостьspring-cloud-starter-consul-config к нашемуpom.xml:


    org.springframework.cloud
    spring-cloud-starter-consul-config
    1.3.0.RELEASE

Нам также необходимо переместить настройки имени приложения 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” в качестве значения. Наконец, нажмите кнопку“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 будут иметь одинаковое значение“Hello World” из Consul.

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

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

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

Это потому, что полеproperties является классомMyProperties и имеет аннотацию@RefreshScope. All beans annotated with the @RefreshScope annotation will be refreshed after configuration changes.

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

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

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

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

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