Spring Boot 2.0 中的执行器端点介绍

工程 | 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 开始,对“响应式”执行器的支持成为一个显而易见的需求,这也带来了许多新的挑战。

端点基础设施

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 端点

此端点公开了三个操作

  • /application/loggersGET 请求:所有日志记录器的配置(因为它没有“选择器”参数)

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

  • /application/loggers/{name}POST 请求:更新命名日志记录器的配置。此操作具有一个附加参数,需要解析它,因为它不用于进一步选择要更新的资源。在本例中,需要一个带有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 分支。

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

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 社区中所有即将举行的活动。

查看全部