Spring Boot 2.0 中的 Actuator 端点介绍

工程 | Stéphane Nicoll | 2017 年 8 月 22 日 | ...

Spring Boot 2 对 Actuator 带来了重要的改变,我很高兴能代表团队,向大家预告在 2.0.0.M4 中即将推出的内容。

开发一个主要的新版本让我们有机会重新审视一些公共契约并加以改进。我们很快就觉得端点基础设施就是其中之一:目前,Actuator 中的 Web 端点仅支持 Spring MVC(不支持 JAX-RS)。此外,创建一个暴露多个操作的新端点需要编写相当多的样板代码:你需要编写一个主端点、Spring MVC 扩展(作为 @RestController)、一个 JMX MBean 以及必要的自动配置。从 Spring Boot 2 开始,支持“响应式” Actuator 成了一个明显的需求,这也带来了新的挑战。

端点基础设施

Spring Boot 2 带来了全新的端点基础设施,它允许你以技术无关的方式定义一个或多个操作,并支持 Spring MVC、Spring WebFlux 和 Jersey!Spring Boot 2 将原生支持 Jersey,只要存在通过编程方式注册资源的方法,为其他 JAX-RS 实现编写适配器应该很容易。

让我们以现有的 /application/loggers MVC 端点来演示新 API,该端点允许你在运行时控制日志配置。此端点有三个操作

  • 一个主要操作,列出当前配置。

  • 一个更精细的操作,按名称提供特定日志器的配置。

  • 一个写操作,用于更新特定日志器的配置。

这就是从 Spring Boot 2 开始,该端点的样子

@Endpoint(id = "loggers")
public class LoggersEndpoint {

    @ReadOperation
    public Map<String, Object> loggers() { ... }

    @ReadOperation
    public LoggerLevels loggerLevels(@Selector String name) { ... }

    @WriteOperation
    public void configureLogLevel(@Selector String name, LogLevel configuredLevel) { ... }

}

新的 @Endpoint 注解将此类声明为一个端点,并具有一个强制的唯一 ID。正如我们稍后将看到的,很多属性将由此自动推断出来。无需额外代码即可将此端点暴露在 /applications/loggers 或作为一个 org.springframework.boot:type=Endpoint,name=Loggers JMX MBean。让我们看看为什么。

Web 端点

此端点暴露了三个操作

  • GET 访问 /application/loggers:所有日志器的配置(因为它没有“选择器”参数)

  • GET 访问 /application/loggers/{name}:命名日志器的配置(使用 name @Selector)。

  • POST 访问 /application/loggers/{name}:更新命名日志器的配置。此操作有一个附加参数需要解析,因为它不用于进一步选择要更新的资源。在这种特殊情况下,需要一个带有 configuredLevel JSON 属性的请求体,类似这样:

{
    "configuredLevel": "WARN"
}

读操作的附加参数将自动从请求属性中映射。

JMX MBean

无需额外代码即可将该端点作为 JMX MBean 暴露。由于典型的 JMX 客户端(例如 JConsole)无法访问第三方库,因此任何非核心类型都会自动转换。特别是,LogLevel 是一个枚举,它在 configureLogLevel JMX 操作中作为字符串暴露。

横切特性

基础设施允许我们提供横切特性,例如端点缓存。目前,我们提供了一种缓存主操作结果(即上面的 loggers 方法)的方式。端点安全性也正在开发中。

扩展

如果需要以特定技术的方式表达某些内容,可以为其编写扩展。一个例子是健康端点,它需要根据计算出的 Health 改变响应的 HTTP 状态码。health 端点 大体上符合你的预期

@Endpoint(id = "health")
public class HealthEndpoint {

    @ReadOperation
    public Health health() { ... }

}

HealthWebEndpointExtension 重写了主要的读操作,生成 WebEndpointResponse<Health> 而不是 Health。这使得 Web 扩展有机会为响应提供 Web 特定的属性。

@WebEndpointExtension(endpoint = HealthEndpoint.class)
public class HealthWebEndpointExtension {

    private final HealthEndpoint delegate;

    public HealthWebEndpointExtension(HealthEndpoint delegate) { ... }

    @ReadOperation
    public WebEndpointResponse<Health> getHealth() {
        Health health = this.delegate.health();
        Integer status = // get http status based on current health
        return new WebEndpointResponse<>(health, status);
    }

}

配置

每个端点都会在 endpoints 下自动获得一个专用的配置命名空间。spring-boot-configuration-processor 已更新,可以自动检测 @Endpoint

T0HFTViTS1C39qipMg Mhg

要配置一个端点,真正所需的只是将其暴露为一个 @Bean。有一个新的 @ConditionalOnEnabledEndpoint 注解,它确保根据当前配置不会创建(或暴露)该端点。

@Bean
@ConditionalOnBean(LoggingSystem.class)
@ConditionalOnMissingBean
@ConditionalOnEnabledEndpoint
public LoggersEndpoint loggersEndpoint(LoggingSystem loggingSystem) {
	return new LoggersEndpoint(loggingSystem);
}

因此,例如,如果环境中存在 endpoints.loggers.enabled=false,则条件不匹配,端点将完全不暴露。

接下来是什么?

由于我们现在有了集中的基础设施,我们可以根据运行时环境更智能地决定做什么。如果你使用 WebFlux 运行 Actuator,它不一定假定所有内容都是非阻塞的。事实上,不返回 Publisher(即 MonoFlux)的操作将在专用的线程池上运行,这样它们就不会阻塞响应式操作。这项工作应该在下周初合并到 master 分支。

我们还在为 Actuator 开发一些响应式特定的契约,即一个响应式的 Health 端点,可以以响应式方式执行可用的 HealthIndicators

public interface ReactiveHealthIndicator {

    Mono<Health> health();

}

我们也在考虑从 R/W 模型迁移到 CRUD 模型(即支持删除和创建操作),如果您有兴趣,请关注 #10023

如果您想尝试一下这个新的端点基础设施,我们非常乐意听取您的意见。要开始使用,请在 start.spring.io 上使用 Spring Boot 2.0.0.BUILD-SNAPSHOT 生成一个应用程序。

订阅 Spring 电子报

通过 Spring 电子报保持联系

订阅

领先一步

VMware 提供培训和认证,助您加速前进。

了解更多

获取支持

Tanzu Spring 通过一个简单的订阅,提供对 OpenJDK™、Spring 和 Apache Tomcat® 的支持和二进制文件。

了解更多

近期活动

查看 Spring 社区的所有近期活动。

查看全部