Подробное объяснение и подробное применение Spring Boot Actuator (2): Actuator 2.x

Spring Boot Spring MVC Безопасность

Ожидается, что «Подробное объяснение и подробное применение Spring Boot Actuator» будет включать три статьи. Первая статья посвящена приложению и пользовательским конечным точкам Spring Boot Actuator 1.x, а вторая статья посвящена сравнению различий между Spring Boot Actuator 2. x и 1.x. Помимо применения и настройки конечных точек 2.x, в третьей статье будут представлены метрики Actuator в сочетании с использованием Prometheus и Grafana. Эта часть контента является очень распространенной и относительно вводной, и каждый может обратить на нее внимание.

Предыдущий отзыв

Эта статья является второй частью «Подробного объяснения и подробного применения Spring Boot Actuator». В предыдущей статье:Подробное объяснение и подробное применение Spring Boot Actuator (1): Actuator 1.xВ основном речь идет о приложении и пользовательских конечных точках Spring Boot Actuator 1.x. Официальная версия Spring Boot 2.0 была выпущена в течение некоторого времени, и она прибыла2.1.0.RELEASE. Особенности Spring Boot 2.x здесь подробно описываться не будут, но тенденция его популярности очевидна.

В этой статье будут сравниваться различия между Spring Boot Actuator 2.x и 1.x, а также конечные точки для применения и настройки 2.x. Сосредоточьтесь на последней версии 2.x Actuator.

Actuator 2.x

Actuator 2.x сохраняет свою базовую функциональность, но упрощает модель, расширяет функциональность и включает подходящие значения по умолчанию. Во-первых, эта версия отделяется от конкретного фреймворка, более того, она упрощает свою модель безопасности, объединяя ее с приложением, наконец, среди различных изменений некоторые из них огромны, включая HTTP-запрос/ответ, а также предоставление Java API. Кроме того, последняя версия поддерживает модель CRUD вместо старой модели RW (чтение/запись).

В Actuator 1.x он был привязан к Spring MVC и, таким образом, к Servlet API. А в версии 2.x Actuator определяет свою модель как подключаемую и расширяемую, не полагаясь на MVC. Таким образом, с этой новой моделью мы можем использовать WebFlux в качестве базовой веб-технологии, как и MVC. Кроме того, будущие фреймворки могут дополнять эту модель, реализуя специальные адаптеры. JMX по-прежнему поддерживает предоставление конечных точек без дополнительного кода.

быстрый старт

Введите следующие зависимости:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

Нет большой разницы с использованием Spring Boot Actuator 1.x.

Изменения в Актуаторе 2.x

В отличие от предыдущего Actuator 1.x, большинство конечных точек в Actuator 2.x по умолчанию отключены. Конечная точка по умолчанию в Actuator 2.x имеет добавленный префикс /actuator.

По умолчанию доступны две конечные точки: /actuator/health и /actuator/info. Мы можем сделать это, установив следующие свойства:

management.endpoints.web.exposure.include=*

Все конечные точки могут быть открыты. Кроме того, мы также можем перечислить конечные точки, которые необходимо раскрыть, или исключить определенные конечные точки. как:

management.endpoints.web.exposure.exclude=env,beans

конечная точка по умолчанию

Ниже мы рассмотрим доступные конечные точки, большинство из них уже существуют в версии 1.x. Тем не менее, некоторые конечные точки были добавлены, некоторые удалены, а некоторые подверглись рефакторингу.

  • /auditevents: То же, что и в Actuator 1.x, вы также можете фильтровать по ключевому слову.
  • /beans: то же, что и Actuator 1.x, фильтровать нельзя.
  • /conditions: возвращает элементы автоматической конфигурации в сервисе.
  • /configprops: позволяет нам получить@ConfigurationPropertiesбобовый объект
  • /env: возвращает текущую переменную среды, мы также можем получить значение
  • /flyway: предоставляет подробную информацию о миграции базы данных Flyway.
  • /health: то же, что и Actuator 1.x
  • /heapdump: возвращает информацию о дампе кучи jvm, используемую службой приложения.
  • /info: то же, что и Actuator 1.x
  • /liquibase: аналогично /flyway, но компонентом является Liquibase.
  • /logfile: возвращает обычный файл журнала приложения.
  • /loggers: позволяет нам запрашивать и изменять уровень журнала приложения.
  • /metrics: то же, что и Actuator 1.x
  • /prometheus: возвращает аналогично /metrics, используемому с сервером Prometheus.
  • /scheduledtasks: возвращает периодические задачи приложения.
  • /sessions: то же, что и Actuator 1.x
  • /shutdown: то же, что и Actuator 1.x
  • /threaddump: информация о потоке jvm, от которого зависит дамп

Безопасность конечных точек актуатора

Конечные точки актуатора являются конфиденциальными и должны быть защищены от несанкционированного доступа. Если в приложении присутствует Spring Security, по умолчанию конечные точки защищены базовой HTTP-аутентификацией на основе форм. Защита доступа к конечной точке Actuator с помощью Spring Security.

импортировать зависимости

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-security</artifactId>
</dependency>

Конфигурация безопасности

Чтобы применить правила безопасности Actuator, мы добавляем следующую конфигурацию:

@Bean
public SecurityWebFilterChain securityWebFilterChain(
  ServerHttpSecurity http) {
    return http.authorizeExchange()
      .pathMatchers("/actuator/**").permitAll()
      .anyExchange().authenticated()
      .and().build();
}

В приведенной выше конфигурации все URL-адреса, начинающиеся с /actuator, должны быть зарегистрированы. Мы также можем использовать более детализированную конфигурацию:

@Configuration
public class ActuatorSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                    .requestMatchers(EndpointRequest.to(ShutdownEndpoint.class))
                        .hasRole("ACTUATOR_ADMIN")
                    .requestMatchers(EndpointRequest.toAnyEndpoint())
                        .permitAll()
                    .requestMatchers(PathRequest.toStaticResources().atCommonLocations())
                        .permitAll()
                    .antMatchers("/")
                        .permitAll()
                    .antMatchers("/**")
                        .authenticated()
                .and()
                .httpBasic();
    }
}

Вышеупомянутая конфигурация в основном реализует:

  • Роль, которая ограничивает доступ к конечной точке отключения, может быть только ACTUATOR_ADMIN.
  • Разрешить доступ ко всем остальным конечным точкам
  • Разрешить доступ к статическим ресурсам
  • Разрешить доступ к корневому каталогу '/'
  • Все запросы аутентифицируются
  • Разрешить статическую HTTP-аутентификацию (можно использовать любую форму аутентификации)

контрольная работа

Чтобы иметь возможность протестировать приведенную выше конфигурацию с базовой аутентификацией HTTP, можно добавить пользователя безопасности spring по умолчанию:

spring:
  security:
    user:
      name: actuator
      password: actuator
      roles: ACTUATOR_ADMIN

/конечная точка здоровья

Как и в предыдущих версиях, мы можем легко добавлять собственные индикаторы. Абстракция для создания настраиваемых конечных точек работоспособности остается прежней. В отличие от Spring Boot 1.x,endpoints.<id> .sensitiveАтрибут удален. Информация о работоспособности, предоставляемая конечной точкой /health, зависит от:

management.endpoint.health.show-details

Это свойство может быть настроено с одним из следующих значений:

  • никогда: нет подробной информации, статус включен или выключен, конфигурация по умолчанию
  • when-authorized: Детали будут отображаться для аутентифицированных пользователей. Авторизованные роли могут бытьmanagement.endpoint.health.rolesконфигурация.
  • всегда: показывать детали

Конечная точка /health имеет множество автоматически настраиваемых индикаторов работоспособности: такие компоненты, как redis, rabbitmq и т. д.

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

management.health.mongo.enabled: false

Или отключите все автоматически настраиваемые индикаторы работоспособности:

management.health.defaults.enabled: false

В дополнение к этому был добавлен новый интерфейс.ReactiveHealthIndicatorдля реализации реактивных проверок работоспособности.

импортировать зависимости

        <dependency>
            <groupId>io.projectreactor</groupId>
            <artifactId>reactor-core</artifactId>
        </dependency>

Пользовательские реактивные проверки работоспособности

@Component
public class DownstreamServiceHealthIndicator implements ReactiveHealthIndicator {

    @Override
    public Mono<Health> health() {
        return checkDownstreamServiceHealth().onErrorResume(
                ex -> Mono.just(new Health.Builder().down(ex).build())
        );
    }

    private Mono<Health> checkDownstreamServiceHealth() {
        // we could use WebClient to check health reactively
        return Mono.just(new Health.Builder().up().build());
    }
}

Удобная функция показателей работоспособности заключается в том, что мы можем объединять их как часть иерархии. Итак, следуя приведенному выше примеру, мы можем сгруппировать все нижестоящие сервисы в категорию нижестоящих сервисов. Пока доступна каждая вложенная служба, доступ является работоспособным.

/метрики конечной точки

В Spring Boot 2.0 есть bean-компонент типаMeterRegistryбудут автоматически настроены, иMeterRegistryУже включен в зависимости Actuator. Ниже представлена ​​информация о конечных точках /metrics, которую мы получили.

{
  "names": [
    "jvm.gc.pause",
    "jvm.buffer.memory.used",
    "jvm.memory.used",
    "jvm.buffer.count",
    // ...
  ]
}

Видно, что, в отличие от 1.x, мы больше не можем видеть конкретную информацию об индикаторе, а только отображаем список индикаторов. Чтобы получить подробную информацию об индикаторе, мы можем запросить конкретную информацию об индикаторе, такую ​​как/actuator/metrics/jvm.gc.pause

{
	"name": "jvm.gc.pause",
	"description": "Time spent in GC pause",
	"baseUnit": "seconds",
	"measurements": [{
		"statistic": "COUNT",
		"value": 2.0
	}, {
		"statistic": "TOTAL_TIME",
		"value": 0.07300000000000001
	}, {
		"statistic": "MAX",
		"value": 0.0
	}],
	"availableTags": [{
		"tag": "cause",
		"values": ["Metadata GC Threshold"]
	}, {
		"tag": "action",
		"values": ["end of minor GC", "end of major GC"]
	}]
}

Мы видим, что метрики стали более подробными. Не только различные значения, но и некоторые связанные метаданные.

/Информация о конечной точке

Нет никаких изменений в конечной точке /info Мы можем ввести зависимости через maven или gradle, чтобы увеличить детали git.

<dependency>
    <groupId>pl.project13.maven</groupId>
    <artifactId>git-commit-id-plugin</artifactId>
</dependency>

Точно так же мы можем использовать плагины maven и gradle для получения имени, группы и версии сборки (файл META-INF/build-info.properties должен существовать в пути к классам).

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <executions>
        <execution>
            <goals>
                <goal>build-info</goal>
            </goals>
        </execution>
    </executions>
</plugin>

пользовательская конечная точка

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

@Component
@Endpoint(id = "features")
public class FeaturesEndpoint {

    private Map<String, Feature> features = new ConcurrentHashMap<>();

    @ReadOperation
    public Map<String, Feature> features() {
        return features;
    }

    @ReadOperation
    public Feature feature(@Selector String name) {
        return features.get(name);
    }

    @WriteOperation
    public void configureFeature(@Selector String name, Feature feature) {
        features.put(name, feature);
    }

    @DeleteOperation
    public void deleteFeature(@Selector String name) {
        features.remove(name);
    }

    public static class Feature {
        private Boolean enabled;

		//...
    }

}

Путь к конечной точке определяется@EndpointАтрибут id в приведенном выше примере определяет адрес конечной точки запроса./actuator/features. И определите операцию со следующей аннотацией метода:

  • @ReadOperation: HTTP GET
  • @WriteOperation: HTTP POST
  • @DeleteOperation: УДАЛИТЬ HTTP

Запустите приложение, и вы увидите следующий вывод журнала в консоли:

[...].WebFluxEndpointHandlerMapping: Mapped "{[/actuator/features/{name}],
  methods=[GET],
  produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}"
[...].WebFluxEndpointHandlerMapping : Mapped "{[/actuator/features],
  methods=[GET],
  produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}"
[...].WebFluxEndpointHandlerMapping : Mapped "{[/actuator/features/{name}],
  methods=[POST],
  consumes=[application/vnd.spring-boot.actuator.v2+json || application/json]}"
[...].WebFluxEndpointHandlerMapping : Mapped "{[/actuator/features/{name}],
  methods=[DELETE]}"[...]

Приведенный выше журнал показывает, как Webflux раскрывает наши конечные точки.Что касается перехода на Spring MVC, нам нужно только ввести зависимости без изменения кода.

Информация о метаданных (конфиденциальная, включенная) в предыдущем методе больше не используется. Чтобы включить или отключить конечную точку, используйте@Endpoint(id = “features”, enableByDefault = false). По сравнению со старой моделью чтения-записи мы можем использовать@DeleteOperationОпределите операцию DELETE.

конечная точка расширения

Мы также можем использовать аннотации@EndpointExtensionРасширьте предопределенные конечные точки, более точные аннотации:@EndpointWebExtension,@EndpointJmxExtension.

@Component
@EndpointWebExtension(endpoint = InfoEndpoint.class)
public class InfoWebEndpointExtension {
 
    private InfoEndpoint delegate;
 
    @Autowired
    public InfoWebEndpointExtension(InfoEndpoint delegate) {
        this.delegate = delegate;
    }
 
    @ReadOperation
    public WebEndpointResponse<Map> info() {
        Map<String, Object> info = this.delegate.info();
        Integer status = getStatus(info);
        return new WebEndpointResponse<>(info, status);
    }
 
    private Integer getStatus(Map<String, Object> info) {
        // return 5xx if this is a snapshot
        return 200;
    }
}

Суммировать

В этой статье в основном рассказывается о связанных функциях и использовании Actuator 2.x, а также сравнивается разница в использовании с Actuator 1.x. Actuator 2.x не зависит от определенного компонента фреймворка (например, Spring MVC), что упрощает его подключение и расширение. Когда мы хотим переключиться на Webflux через адаптер в Actuator 2.x, мы можем сделать это без изменения кода.Исходный код этой статьи:GitHub.com/Доступный ETS2012/S…

Подписывайтесь на свежие статьи, приглашаю обратить внимание на мой публичный номер

微信公众号

Ссылаться на

  1. Actuator docs
  2. Spring Boot Actuator