20220524 Production-ready Features

前言

文档地址

Spring Boot 包含许多其他功能,可帮助您在将应用程序推送到生产环境时对其进行监控和管理。您可以选择使用 HTTP 端点或 JMX 管理和监视您的应用程序。审计(auditing),健康状况(health)和指标收集(metrics gathering)也可以自动应用于您的应用程序。

1. 启用生产就绪功能(Production-ready Features)

spring-boot-actuator 模块提供了 Spring Boot 的所有生产就绪功能。启用功能的最简单方法是添加依赖项,spring-boot-starter-actuator 启动器。

执行器的定义:

执行器是制造术语,是指用于移动或控制某些物体的机械设备。执行器可以通过很小的变化产生大量的动作。

要将执行器添加到基于 Maven 的项目中,请添加以下依赖项:

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

对于 Gradle ,请使用以下声明:

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
}

2. 端点(Endpoints)

执行器端点使您可以监视应用程序并与之交互。Spring Boot 包含许多内置端点,并允许您添加自己的端点。例如,health 端点提供基本的应用程序健康信息。

您可以 启用或禁用 每个单独的端点以及 通过 HTTP 或 JMX 公开它们(使它们可以远程访问) 。当端点被启用和公开时,它被认为是可用的。内置端点仅在可用时才会自动配置。大多数应用程序选择通过 HTTP 公开,其中端点的 ID 和前缀 /actuator 映射到 URL 。例如,默认情况下,health 端点映射到 /actuator/health

要了解有关执行器端点及其请求和响应格式的更多信息,请参阅单独的 API 文档( HTMLPDF

以下与技术无关的端点可用:

ID 描述
auditevents 公开当前应用程序的审计事件信息。需要一个 AuditEventRepository bean
beans 显示应用程序中所有 Spring beans 的完整列表
caches 公开可用的缓存
conditions 显示在配置和自动配置类上评估的条件以及它们匹配或不匹配的原因
configprops 显示所有 @ConfigurationProperties 的整理列表(collated list)
env 公开 Spring ConfigurableEnvironment 的属性
flyway 显示任何已应用的 Flyway 数据库迁移。需要一个或多个 Flyway beans
health 显示应用程序运行状况信息
httptrace 显示 HTTP 跟踪信息(默认情况下,最近 100 个 HTTP 请求-响应交换)。需要一个 HttpTraceRepository bean
info 显示任意应用程序信息
integrationgraph 显示 Spring Integration 图。需要依赖项 spring-integration-core
loggers 显示和修改应用程序中记录器的配置
liquibase 显示已应用的所有 Liquibase 数据库迁移。需要一个或多个 Liquibase bean
metrics 显示当前应用程序的 “指标”(metrics) 信息
mappings 显示所有 @RequestMapping 路径的整理列表
quartz 显示有关 Quartz Scheduler 作业的信息
scheduledtasks 显示应用程序中的计划任务
sessions 允许从 Spring Session 支持的会话存储中检索和删除用户会话。需要使用 Spring Session 的基于 servlet 的 Web 应用程序
shutdown 让应用程序正常关闭。默认禁用。
startup 显示 ApplicationStartup 收集的 启动步骤数据 。要求将 SpringApplication 配置为 BufferingApplicationStartup
threaddump 执行线程转储

如果您的应用程序是 Web 应用程序(Spring MVC ,Spring WebFlux 或 Jersey),则可以使用以下额外的端点:

ID 描述
heapdump 返回堆转储文件。在 HotSpot JVM 上,返回一个 HPROF 格式文件。在 OpenJ9 JVM 上,返回一个 PHD 格式文件
jolokia 当 Jolokia 在类路径上时,通过 HTTP 公开 JMX bean(不适用于 WebFlux)。需要依赖 jolokia-core
logfile 返回日志文件的内容(如果已设置 logging.file.namelogging.file.path 属性)。支持使用 HTTP Range 标头来检索部分日志文件的内容
prometheus 以 Prometheus 服务器可以抓取的格式公开指标。需要依赖 micrometer-registry-prometheus

2.1. 启用端点

默认情况下,所有端点除 shutdown 外均处于启用状态。要配置端点的启用,请使用 management.endpoint.<id>.enabled 属性。以下示例启用 shutdown 端点:

management.endpoint.shutdown.enabled=true

如果您希望端点启用是选择加入而不是选择退出,请将 management.endpoints.enabled-by-default 属性设置为 false ,并设置各个端点 enabled 属性重新启用。以下示例启用 info 端点并禁用所有其他端点:

management.endpoints.enabled-by-default=false
management.endpoint.info.enabled=true

禁用的端点将从应用上下文中完全删除。如果只想更改公开端点的技术,请使用 includeexclude 属性

2.2. 公开端点

由于端点可能包含敏感信息,您应该仔细考虑何时公开它们。下表显示了内置端点的默认公开:

ID JMX Web
auditevents Yes No
beans Yes No
caches Yes No
conditions Yes No
configprops Yes No
env Yes No
flyway Yes No
health Yes Yes
heapdump N/A No
httptrace Yes No
info Yes No
integrationgraph Yes No
jolokia N/A No
logfile N/A No
loggers Yes No
liquibase Yes No
metrics Yes No
mappings Yes No
prometheus N/A No
quartz Yes No
scheduledtasks Yes No
sessions Yes No
shutdown Yes No
startup Yes No
threaddump Yes No

要更改公开的端点,请使用以下技术特定的 includeexclude 属性:

Property Default
management.endpoints.jmx.exposure.exclude
management.endpoints.jmx.exposure.include *
management.endpoints.web.exposure.exclude
management.endpoints.web.exposure.include health

include 属性列出了公开的端点的 ID 。exclude 属性列出不应公开的端点的 ID 。exclude 属性优先于 include 属性。您可以使用端点 ID 列表来配置 includeexclude 属性。

例如,要停止通过 JMX 公开所有端点并仅公开 healthinfo 端点,请使用以下属性:

management.endpoints.jmx.exposure.include=health,info

* 可用于选择所有端点。例如,要通过 HTTP 公开除 envbeans 端点之外的所有内容,请使用以下属性:

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

* 在 YAML 中具有特殊含义,因此如果要包含(或排除)所有端点,请务必添加引号

如果您的应用程序是公开的,我们强烈建议您 保护您的端点

如果您想在端点公开时实现自己的策略,您可以注册一个 EndpointFilter bean

2.3. Security

出于安全目的,默认情况下只有 /health 端点通过 HTTP 公开。您可以使用 management.endpoints.web.exposure.include 属性来配置公开的端点。

在设置 management.endpoints.web.exposure.include 之前,请确保公开的执行器不包含敏感信息,通过将它们放在防火墙后面来保护它们,或者通过 Spring Security 之类的东西来保护它们。

如果 Spring Security 在 classpath 上并且没有其他 WebSecurityConfigurerAdapterSecurityFilterChain bean 存在,则除 /health 之外的所有执行器都受到 Spring Boot 自动配置保护。如果您定义了自定义 WebSecurityConfigurerAdapterSecurityFilterChain bean ,Spring Boot 自动配置会退出并让您完全控制执行器访问规则。

如果您希望为 HTTP 端点配置自定义安全(例如,只允许具有特定角色的用户访问它们),Spring Boot 提供了一些方便 RequestMatcher 的对象,您可以将它们与 Spring Security 结合使用。

典型的 Spring Security 配置可能类似于以下示例:

import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;

@Configuration(proxyBeanMethods = false)
public class MySecurityConfiguration {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.requestMatcher(EndpointRequest.toAnyEndpoint())
                .authorizeRequests((requests) -> requests.anyRequest().hasRole("ENDPOINT_ADMIN"));
        http.httpBasic();
        return http.build();
    }

}

前面的示例使用 EndpointRequest.toAnyEndpoint() 将请求匹配到任何端点,然后确保所有端点都具有 ENDPOINT_ADMIN 角色。其他几种匹配器方法也可以在 EndpointRequest 上可用。有关详细信息,请参阅 API 文档( HTMLPDF )。

如果您在防火墙后面部署应用程序,您可能希望无需身份验证即可访问所有执行器端点。您可以通过更改 management.endpoints.web.exposure.include 属性来做到这一点,如下所示:

management.endpoints.web.exposure.include=*

此外,如果存在 Spring Security,您将需要添加自定义安全配置,以允许未经身份验证的访问端点,如以下示例所示:

import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;

@Configuration(proxyBeanMethods = false)
public class MySecurityConfiguration {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.requestMatcher(EndpointRequest.toAnyEndpoint())
                .authorizeRequests((requests) -> requests.anyRequest().permitAll());
        return http.build();
    }

}

在前面的两个示例中,配置仅适用于执行器端点。由于 Spring Boot 的安全配置在任何 SecurityFilterChain bean 存在的情况下都会完全退出,因此您需要配置一个额外的 SecurityFilterChain bean ,其规则适用于应用程序的其余部分。

2.3.1. 跨站点请求伪造保护

由于 Spring Boot 依赖于 Spring Security 的默认设置,因此默认开启 CSRF 保护。这意味着在使用默认安全配置时,需要 POST(关闭和记录器端点)、PUTDELETE 的执行器端点会收到 403(forbidden)错误。

我们建议仅在创建非浏览器客户端使用的服务时完全禁用 CSRF 保护。

您可以在 Spring Security Reference Guide 中找到有关 CSRF 保护的更多信息。

2.4. 配置端点

端点会自动缓存对不带任何参数的读取操作的响应。要配置端点缓存响应的时间量,请使用 cache.time-to-live 属性。以下示例将 beans 端点缓存的生存时间设置为 10 秒:

management.endpoint.beans.cache.time-to-live=10s

management.endpoint.<name> 前缀唯一标识正在配置的端点 。

2.5. Hypermedia for Actuator Web Endpoints

添加了一个“发现页面”,其中包含指向所有端点的链接。默认情况下,“发现页面” /actuator 可用。

要禁用“发现页面”,请将以下属性添加到您的应用程序属性中:

management.endpoints.web.discovery.enabled=false

配置自定义管理上下文路径后,“发现页面”会自动从 /actuator 移动到管理上下文的根目录。例如,如果管理上下文路径是 /management ,那么发现页面可以从 /management 获得。当管理上下文路径设置为 / 时,发现页面被禁用以防止与其他映射发生冲突的可能性。

2.6. CORS 支持

跨域资源共享 (CORS) 是一种 W3C 规范 ,可让您以灵活的方式指定授权哪种跨域请求。如果您使用 Spring MVC 或 Spring WebFlux ,则可以配置 Actuator 的 Web 端点以支持此类场景。

CORS 支持默认被禁用,只有在您设置了 management.endpoints.web.cors.allowed-origins 属性后才会启用。以下配置允许来自 example.com 域的 GETPOST 调用:

management.endpoints.web.cors.allowed-origins=https://example.com
management.endpoints.web.cors.allowed-methods=GET,POST

有关选项的完整列表,请参阅 CorsEndpointProperties

2.7. 实现自定义端点

如果您添加带有 @Endpoint 注解的任何 @Bean 方法,那么任何带有 @ReadOperation@WriteOperation@DeleteOperation 注解的方法都会自动通过 JMX 公开,并且在 Web 应用程序中,也会通过 HTTP 公开。可以使用 Jersey、Spring MVC 或 Spring WebFlux 通过 HTTP 公开端点。如果 Jersey 和 Spring MVC 都可用,则使用 Spring MVC

以下示例公开了一个返回自定义对象的读取操作:

@ReadOperation
public CustomData getData() {
    return new CustomData("test", 5);
}

您还可以使用 @JmxEndpoint@WebEndpoint 编写特定于技术的端点。这些端点仅限于各自的技术。例如,@WebEndpoint 仅通过 HTTP 而不是通过 JMX 公开。

您可以使用 @EndpointWebExtension@EndpointJmxExtension 编写特定于技术的扩展。这些注解让您可以提供特定于技术的操作来扩充现有端点。

最后,如果您需要访问特定于 web 框架的功能,您可以实现 servlet 或 Spring @Controller@RestController 端点,代价是它们不能通过 JMX 或使用不同的 web 框架访问。

2.7.1. 接收输入

端点上的操作通过其参数接收输入。当通过 Web 公开时,这些参数的值取自 URL 的查询参数和 JSON 请求正文。通过 JMX 公开时,参数将映射到 MBean 操作的参数。默认情况下需要参数。可以通过使用 @javax.annotation.Nullable@org.springframework.lang.Nullable 注解来使它们成为可选的。

您可以将 JSON 请求正文中的每个根属性映射到端点的参数。考虑以下 JSON 请求正文:

{
    "name": "test",
    "counter": 42
}

您可以使用它来调用接受 String nameint counter 参数的写入操作,如以下示例所示:

@WriteOperation
public void updateData(String name, int counter) {
    // injects "test" and 42
}

因为端点与技术无关,所以只能在方法签名中指定简单类型。特别是,不支持使用定义 namecounter 属性的 CustomData 类型声明单个参数。

为了让输入映射到操作方法的参数,实现端点的 Java 代码应该用 -parameters 编译,实现端点的 Kotlin 代码应该用 -java-parameters 编译。如果您使用 Spring Boot 的 Gradle 插件或使用 Maven 和 spring-boot-starter-parent ,这将自动发生

输入类型转换

如果需要,传递给端点操作方法的参数将自动转换为所需的类型。在调用操作方法之前,通过 JMX 或 HTTP 接收的输入通过使用 ApplicationConversionService 实例以及任何带有 @EndpointConverter 限定的 ConverterGenericConverter bean 转换为所需的类型。

2.7.2. 自定义 Web 端点

使用 Jersey、Spring MVC 或 Spring WebFlux 通过 HTTP 自动公开 @Endpoint@WebEndpoint@EndpointWebExtension 上的操作。如果 Jersey 和 Spring MVC 都可用,则使用 Spring MVC 。

Web 端点请求断言(Predicate)

为 Web 公开端点上的每个操作自动生成请求断言。

Path

断言的路径由端点的 ID 和 Web 公开的端点的基本路径确定。默认基本路径是 /actuator 。例如,ID 为 sessions 的端点在断言中用 /actuator/sessions 作其路径。

您可以通过使用 @Selector 注解操作方法的一个或多个参数来进一步自定义路径。这样的参数作为路径变量添加到路径断言中。当调用端点操作时,变量的值被传递到操作方法中。如果要捕获所有剩余的路径元素,可以添加 @Selector(Match=ALL_REMAINING) 到最后一个参数并使其成为与 String[] 转换兼容的类型。

HTTP method

断言的 HTTP 方法由操作类型决定,如下表所示:

Operation HTTP method
@ReadOperation GET
@WriteOperation POST
@DeleteOperation DELETE
Consumes

对于使用请求体的 @WriteOperation (HTTP POST) ,断言的 consume 子句是 application/vnd.spring-boot.actuator.v2+json, application/json ,对于所有其他操作,consumes 子句为空。

Produces

断言的 produces 子句可以由 @DeleteOperation@ReadOperation@WriteOperation 注解的 produces 属性确定。属性是可选的。如果未使用,则自动确定 produces 子句。

如果操作方法返回 voidVoid ,则 produces 子句为空。如果操作方法返回一个 org.springframework.core.io.Resourceproduces 的子句是 application/octet-stream 。对于所有其他操作,produces 子句是 application/vnd.spring-boot.actuator.v2+json, application/json

Web Endpoint Response Status

端点操作的默认响应状态取决于操作类型(读取、写入或删除)以及操作返回的内容(如果有)。

如果 @ReadOperation 返回一个值,则响应状态将为 200(OK)。如果它没有返回值,则响应状态将为 404(未找到)。

如果 @WriteOperation@DeleteOperation 返回值,则响应状态将为 200(OK)。如果它没有返回值,则响应状态将为 204(无内容)。

如果调用操作时不带必填参数或带有无法转换为所需类型的参数,则不会调用操作方法,响应状态为 400(Bad Request)。

Web Endpoint Range Requests

您可以使用 HTTP range 请求来请求 HTTP 资源的一部分。使用 Spring MVC 或 Spring Web Flux 时,返回 org.springframework.core.io.Resource 自动支持范围请求的操作。

使用 Jersey 时不支持范围请求。

Web Endpoint Security

Web 端点或特定于 Web 的端点扩展上的操作可以接收当前 java.security.Principalorg.springframework.boot.actuate.endpoint.SecurityContext 作为方法参数。前者通常与 @Nullable 结合使用,为经过身份验证和未经身份验证的用户提供不同的行为。后者通常用于通过使用其 isUserInRole(String) 方法执行授权检查。

2.7.3. Servlet 端点

通过实现一个带有 @ServletEndpoint 注解的类,也实现了 Supplier<EndpointServlet> ,servlet 可以作为端点公开。Servlet 端点提供与 servlet 容器的更深层次的集成,但以牺牲可移植性为代价。它们旨在用于将现有 servlet 公开为端点。对于新端点,应尽可能首选 @Endpoint@WebEndpoint 注解。

2.7.4. Controller Endpoints

您可以使用 @ControllerEndpoint@RestControllerEndpoint 来实现只由 Spring MVC 或 Spring WebFlux 公开的端点。方法通过使用 Spring MVC 和 Spring WebFlux 的标准注解 (如 @RequestMapping@GetMapping ) 进行映射,并使用端点的 ID 作为路径的前缀。控制器端点提供了与 Spring 的 web 框架的更深层次的集成,但代价是可移植性。只要有可能,应尽可能首选 @Endpoint@WebEndpoint 注解。

2.8. Health Information

您可以使用健康信息来检查正在运行的应用程序的状态。当生产系统出现故障时,监控软件经常使用它来提醒某人。health 端点公开的信息取决于 management.endpoint.health.show-detailsmanagement.endpoint.health.show-components 属性,可以使用以下值之一进行配置:

姓名 描述
never 从不显示细节
when-authorized 详细信息仅向授权用户显示。可以使用 management.endpoint.health.roles 配置授权角色
always 向所有用户显示详细信息

默认值为 never 。当用户处于一个或多个端点角色时,他们被认为是被授权的。如果端点没有配置角色(默认),则所有经过身份验证的用户都被认为是授权的。您可以使用 management.endpoint.health.roles 属性来配置角色。

如果您已保护应用程序并希望使用 always ,则您的安全配置必须允许经过身份验证和未经身份验证的用户访问 health 端点

健康信息是从 HealthContributorRegistry 的内容中收集的(默认情况下,您的 ApplicationContext 中定义的所有 HealthContributor 实例)。Spring Boot 包含了一些自动配置的 HealthContributors ,你也可以自己编写。

HealthContributor 可以是 HealthIndicatorCompositeHealthContributorHealthIndicator 提供实际的健康信息,包括StatusCompositeHealthContributor 提供了其他 HealthContributors 的组合。总之,贡献者形成了一个树结构来表示整个系统的健康状况。

默认情况下,最终系统运行状况由 StatusAggregator 派生,它根据状态的有序列表对每个状态进行排序。HealthIndicator 排序列表中的第一个状态用作整体健康状态。如果没有 HealthIndicator 返回 StatusAggregator 已知的状态,则使用 UNKNOWN 状态。

您可以使用 HealthContributorRegistry 来在运行时注册和取消注册健康指标。

2.8.1. 自动配置的 HealthIndicator

在适当的时候,Spring Boot 会自动配置下表中列出的 HealthIndicators 。您也可以通过配置 management.health.key.enabled 启用或禁用选定的指标,使用下表中的 key

Key Name 描述
cassandra CassandraDriverHealthIndicator 检查 Cassandra 数据库是否已启动
couchbase CouchbaseHealthIndicator 检查 Couchbase 集群是否已启动
db DataSourceHealthIndicator 检查是否可以获得 DataSource 连接
diskspace DiskSpaceHealthIndicator 检查是否磁盘空间不足
elasticsearch ElasticsearchRestHealthIndicator 检查 Elasticsearch 集群是否已启动
hazelcast HazelcastHealthIndicator 检查 Hazelcast 服务器是否已启动
influxdb InfluxDbHealthIndicator 检查 InfluxDB 服务器是否已启动
jms JmsHealthIndicator 检查 JMS 代理是否已启动
ldap LdapHealthIndicator 检查 LDAP 服务器是否已启动
mail MailHealthIndicator 检查邮件服务器是否已启动
mongo MongoHealthIndicator 检查 Mongo 数据库是否已启动
neo4j Neo4jHealthIndicator 检查 Neo4j 数据库是否已启动
ping PingHealthIndicator 始终以 UP 响应
rabbit RabbitHealthIndicator 检查 Rabbit 服务器是否已启动
redis RedisHealthIndicator 检查 Redis 服务器是否已启动
solr SolrHealthIndicator 检查 Solr 服务器是否已启动

您可以通过设置 management.health.defaults.enabled 属性来禁用它们

其他 HealthIndicators 可用但默认情况下未启用:

Key Name 描述
livenessstate LivenessStateHealthIndicator 公开 Liveness 应用程序可用性状态
readinessstate ReadinessStateHealthIndicator 公开 Readiness 应用程序可用性状态

2.8.2. 编写自定义 HealthIndicator

要提供自定义健康信息,您可以注册实现 HealthIndicator 接口的 Spring bean 。您需要提供 health() 方法的实现并返回 Health 响应。Health 响应应包含状态,并且可以选择包含要显示的其他详细信息。以下代码显示了一个示例 HealthIndicator 实现:

import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.stereotype.Component;

@Component
public class MyHealthIndicator implements HealthIndicator {

    @Override
    public Health health() {
        int errorCode = check();
        if (errorCode != 0) {
            return Health.down().withDetail("Error Code", errorCode).build();
        }
        return Health.up().build();
    }

    private int check() {
        // perform some specific health check
        return ...
    }

}

给定 HealthIndicator 的标识符是不带 HealthIndicator 后缀的 bean 的名称(如果存在)。在前面的示例中,健康信息位于名为 my 的条目中

除了 Spring Boot 的预定义 Status 类型之外,Health 还可以返回一个表示新系统状态的自定义 Status 。在这种情况下,您还需要提供 StatusAggregator 接口的自定义实现,或者您必须使用 management.endpoint.health.status.order 配置属性配置默认实现。

例如,假设在您的一个 HealthIndicator 实现中使用了编码为 FATAL 的新 Status 。要配置严重性顺序,请将以下属性添加到您的应用程序属性中:

management.endpoint.health.status.order=fatal,down,out-of-service,unknown,up

响应中的 HTTP 状态代码反映了整体健康状况。默认情况下,OUT_OF_SERVICEDOWN 映射到 503。任何未映射的健康状态,包括 UP ,都映射到 200 。如果您通过 HTTP 访问健康端点,您可能还需要注册自定义状态映射。配置自定义映射会禁用 DOWNOUT_OF_SERVICE 的默认映射。如果要保留默认映射,则必须显式配置它们以及任何自定义映射。例如,以下属性映射 FATAL 到 503(服务不可用)并保留 DOWNOUT_OF_SERVICE 的默认映射:

management.endpoint.health.status.http-mapping.down=503
management.endpoint.health.status.http-mapping.fatal=503
management.endpoint.health.status.http-mapping.out-of-service=503

如果需要更多控制,可以定义自己的 HttpCodeStatusMapper bean

下表显示了内置状态的默认状态映射:

Status Mapping
DOWN SERVICE_UNAVAILABLE ( 503 )
OUT_OF_SERVICE SERVICE_UNAVAILABLE ( 503 )
UP 默认没有映射,所以 HTTP 状态是 200
UNKNOWN 默认没有映射,所以 HTTP 状态是 200

2.8.3. 反应式健康指标

对于响应式应用程序,例如使用 Spring WebFlux 的应用程序,ReactiveHealthContributor 提供了一个非阻塞契约来获取应用程序健康。与传统的 HealthContributor 类似,健康信息是从 ReactiveHealthContributorRegistry 的内容中收集的(默认情况下, 您的 ApplicationContext 中定义的所有 HealthContributorReactiveHealthContributor 实例)。常规 HealthContributors 不检查响应式 API 在 elastic scheduler 上的执行。

在反应式应用程序中,您应该使用 ReactiveHealthContributorRegistry 来在运行时注册和取消注册健康指标。如果你需要注册一个常规的 HealthContributor ,你应该用 ReactiveHealthContributor#adapt 包装

要从反应式 API 提供自定义健康信息,您可以注册实现 ReactiveHealthIndicator 接口的 Spring bean 。以下代码显示了一个示例 ReactiveHealthIndicator 实现:

import reactor.core.publisher.Mono;

import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.ReactiveHealthIndicator;
import org.springframework.stereotype.Component;

@Component
public class MyReactiveHealthIndicator implements ReactiveHealthIndicator {

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

    private Mono<Health> doHealthCheck() {
        // perform some specific health check
        return ...
    }

}

要自动处理错误,请考虑从 AbstractReactiveHealthIndicator 继承

2.8.4. 自动配置的 ReactiveHealthIndicator

在适当的时候,Spring Boot 会自动配置以下 ReactiveHealthIndicators

钥匙 姓名 描述
cassandra CassandraDriverReactiveHealthIndicator 检查 Cassandra 数据库是否已启动
couchbase CouchbaseReactiveHealthIndicator 检查 Couchbase 集群是否已启动
elasticsearch ElasticsearchReactiveHealthIndicator 检查 Elasticsearch 集群是否已启动
mongo MongoReactiveHealthIndicator 检查 Mongo 数据库是否已启动
neo4j Neo4jReactiveHealthIndicator 检查 Neo4j 数据库是否已启动
redis RedisReactiveHealthIndicator 检查 Redis 服务器是否已启动

如有必要,反应式指标会取代常规指标。此外,任何未明确处理的 HealthIndicator 都会被自动包装。

2.8.5. Health Groups

有时将健康指标组织成可用于不同目的的组很有用。

要创建运行状况指标组,您可以使用该management.endpoint.health.group.<name>属性并将运行状况指标 ID 列表指定为includeexclude。例如,要创建仅包含数据库指标的组,您可以定义以下内容:

management.endpoint.health.group.custom.include=db

然后,您可以通过访问 localhost:8080/actuator/health/custom 来检查结果。

同样,要创建一个从组中排除数据库指标并包含所有其他指标的组,您可以定义以下内容:

management.endpoint.health.group.custom.exclude=db

默认情况下,组继承与系统运行状况相同的 StatusAggregatorHttpCodeStatusMapper 设置。但是,您也可以在每个组的基础上定义这些。如果需要,您还可以覆盖 show-detailsroles 属性:

management.endpoint.health.group.custom.show-details=when-authorized
management.endpoint.health.group.custom.roles=admin
management.endpoint.health.group.custom.status.order=fatal,up
management.endpoint.health.group.custom.status.http-mapping.fatal=500
management.endpoint.health.group.custom.status.http-mapping.out-of-service=500

如果您需要注册自定义 StatusAggregatorHttpCodeStatusMapper bean 以与组一起使用,则可以使用 @Qualifier("groupname")

健康组还可以包括/排除 CompositeHealthContributor 。您还可以仅包含/排除 CompositeHealthContributor 的某个组件。这可以使用组件的完全限定名称来完成,如下所示:

management.endpoint.health.group.custom.include="test/primary"
management.endpoint.health.group.custom.exclude="test/primary/b"

在上面的示例中,custom 组将包含 HealthContributor ,其名称为 primary ,是组合 test 的一个组件。在这里,primary 本身是一个组合体,名称为 bHealthContributor 将被排除在 custom 组之外。

可以在主端口或管理端口上的附加路径上提供健康组。这在 Kubernetes 等云环境中很有用,在这些环境中,出于安全目的,为执行器端点使用单独的管理端口是很常见的。拥有一个单独的端口可能会导致不可靠的健康检查,因为即使健康检查成功,主应用程序也可能无法正常工作。可以为健康组配置额外的路径,如下所示:

management.endpoint.health.group.live.additional-path="server:/healthz"

这将使 live 健康组在主服务器端口上可用 /healthz 。前缀是强制性的,必须是 server:(表示主服务器端口)或 management:(表示管理端口,如果已配置)。路径必须是单个路径段。

2.8.6. DataSource Health

DataSource 健康指标显示标准数据源和路由数据源 bean 的运行状况。路由数据源的健康状况包括其每个目标数据源的健康状况。在健康端点的响应中,每个路由数据源的目标都使用其路由键命名。如果您不想在指标的输出中包含路由数据源,请设置 management.health.db.ignore-routing-data-sourcestrue

2.9. Kubernetes 探针(Probe)

部署在 Kubernetes 上的应用程序可以通过 Container Probes 提供有关其内部状态的信息。根据 您的 Kubernetes 配置 ,kubelet 会调用这些探针并对结果做出反应。

默认情况下,Spring Boot 管理您的 应用程序可用性状态 。如果部署在 Kubernetes 环境中,actuator 从 ApplicationAvailability 接口收集 “Liveness” 和 “Readiness” 信息,并在专用的 健康指标 中使用该信息:LivenessStateHealthIndicatorReadinessStateHealthIndicator 。这些指标显示在全局健康端点 ( "/actuator/health" ) 上。它们还通过使用 健康组"/actuator/health/liveness""/actuator/health/readiness" )公开为单个 HTTP 探针。

然后,您可以使用以下端点信息配置 Kubernetes 基础架构:

livenessProbe:
  httpGet:
    path: "/actuator/health/liveness"
    port: <actuator-port>
  failureThreshold: ...
  periodSeconds: ...

readinessProbe:
  httpGet:
    path: "/actuator/health/readiness"
    port: <actuator-port>
  failureThreshold: ...
  periodSeconds: ...

<actuator-port> 应设置为执行器端点可用的端口。如果已设置 management.server.port 属性,它可能是主 Web 服务器端口或单独的管理端口。

只有当应用程序 在 Kubernetes 环境中运行时 ,这些健康组才会自动启用。您可以使用 management.endpoint.health.probes.enabled 配置属性在任何环境中启用它们。

如果应用程序的启动时间比配置的活跃期(liveness period)更长,Kubernetes 提到 startupProbe 是一个可能的解决方案。这里不一定需要 startupProbe ,因为在 readinessProbe 在所有启动任务完成之前都会失败。请参阅 how probes behave during the application lifecycle

如果您的 Actuator 端点部署在单独的管理上下文中,则端点不会使用与主应用程序相同的 Web 基础设施(端口、连接池、框架组件)。在这种情况下,即使主应用程序无法正常工作(例如,它不能接受新连接),探针检查也可能会成功。出于这个原因,让主服务器端口上的 livenessreadiness 健康组可用是一个好主意。这可以通过设置以下属性来完成:

management.endpoint.health.probes.add-additional-paths=true

这将使 liveness/livez )和 readinessreadyz )在主服务器端口可用

2.9.1. 使用 Kubernetes 探针检查外部状态

Actuator 将 “liveness” 和 “readiness” 探针配置为 Health Groups 。这意味着他们可以使用所有 健康组功能 。例如,您可以配置其他健康指标:

management.endpoint.health.group.readiness.include=readinessState,customCheck

默认情况下,Spring Boot 不会向这些组添加其他健康指标。

liveness 探针不应依赖于外部系统的健康检查。如果 应用程序的 liveness 状态 被破坏,Kubernetes 会尝试通过重新启动应用程序实例来解决该问题。这意味着如果外部系统(例如数据库、Web API 或外部缓存)发生故障,Kubernetes 可能会重新启动所有应用程序实例并产生级联故障。

至于 readiness 探针,应用程序开发人员必须仔细选择检查外部系统。出于这个原因,Spring Boot 在 readiness 探针中不包括任何额外的健康检查。如果 应用程序实例的 readiness 状态 未就绪,Kubernetes 不会将流量路由到该实例。某些外部系统可能不被应用程序实例共享,在这种情况下,它们可以包含在 readiness 探针中。其他外部系统可能对应用程序不是必需的(应用程序可能有断路器(circuit breakers)和回退(fallbacks)),在这种情况下,它们绝对不应该包括在内。不幸的是,所有应用程序实例共享的外部系统是常见的,您必须做出判断:将其包含在 readiness 探针中,并期望在外部服务关闭时应用程序停止服务或将其排除在外并处理堆栈更高的故障,也许通过在调用者中使用断路器。

如果应用程序的所有实例都未就绪,则具有 type=ClusterIPNodePort 的 Kubernetes 服务不接受任何传入连接。没有 HTTP 错误响应(503 等),因为没有连接。具有 type=LoadBalancer 的服务可能会或不会接受连接,具体取决于供应商。具有显式 入口(ingress) 的服务也会以取决于实现的方式响应—— 入口服务本身必须决定如何处理来自下游的“连接被拒绝”。在负载均衡器和入口的情况下,很可能出现 HTTP 503

此外,如果应用程序使用 Kubernetes 自动缩放 ,它可能会对从负载均衡器中取出的应用程序做出不同的反应,具体取决于其自动缩放器配置。

2.9.2. 应用程序生命周期和探针状态

Kubernetes Probes 支持的一个重要方面是它与应用程序生命周期的一致性。AvailabilityState(这是应用程序的内存中的内部状态)和实际的探针(公开该状态)之间存在显着差异。根据应用程序生命周期的阶段,探针可能不可用。

Spring Boot 在启动和关闭期间发布应用程序事件 ,探针可以监听此类事件并公开 AvailabilityState 信息。

下表显示了 HTTP 连接器在不同阶段的 AvailabilityState 和状态

当 Spring Boot 应用程序启动时:

Startup phase LivenessState ReadinessState HTTP server Notes
Starting BROKEN REFUSING_TRAFFIC Not started Kubernetes 检查 liveness Probe ,如果时间过长则重新启动应用程序
Started CORRECT REFUSING_TRAFFIC Refuses requests 应用上下文被刷新。应用程序执行启动任务,但尚未接收流量
Ready CORRECT ACCEPTING_TRAFFIC Accepts requests 启动任务完成。应用程序正在接收流量

当 Spring Boot 应用程序关闭时:

Shutdown phase Liveness State Readiness State HTTP server Notes
Running CORRECT ACCEPTING_TRAFFIC 接受请求 已请求关机
Graceful shutdown CORRECT REFUSING_TRAFFIC 新请求被拒绝 如果启用,优雅关闭处理正在进行的请求
Shutdown complete N/A N/A 服务器已关闭 应用上下文关闭,应用程序关闭

有关 Kubernetes 部署的更多信息,请参阅 Kubernetes 容器生命周期部分

2.10. 应用信息

应用程序信息公开了您的 ApplicationContext 里定义的所有 InfoContributor bean 收集的各种信息。Spring Boot 包含许多自动配置的 InfoContributor bean ,您可以编写自己的。

2.10.1. 自动配置的 InfoContributors

在适当的时候,Spring 会自动配置以下 InfoContributor bean :

ID Name 描述 先决条件
build BuildInfoContributor 公开构建信息 META-INF/build-info.properties
env EnvironmentInfoContributor 公开 Environment 中名称以 info. 开头的任何属性 None
git GitInfoContributor 公开 git 信息 git.properties
java JavaInfoContributor 公开 Java 运行时信息 None

是否启用单个贡献者由 management.info.<id>.enabled 属性控制。不同的贡献者对此属性有不同的默认值,这取决于他们的先决条件和他们公开的信息的性质。

没有先决条件表明应该启用它们,默认情况下禁用 envjava 贡献者。您可以通过将 management.info.env.enabledmanagement.info.java.enabled 属性设置为 true 来启用它们。

buildgit 信息贡献者默认启用。每个都可以通过将 management.info.<id>.enabled 属性设置为 false 来禁用。或者,要禁用通常默认启用的每个贡献者,请将 management.info.defaults.enabled 属性设置为 false

2.10.2. 自定义应用程序信息

启用 env 贡献者后,您可以通过设置 Spring 属性 info.* 来自定义 info 端点公开的数据。info 键下的所有 Environment 属性都会自动公开。例如,您可以将以下设置添加到 application.properties 文件中:

info.app.encoding=UTF-8
info.app.java.source=11
info.app.java.target=11

除了硬编码这些值,您还可以 在构建时扩展 info 属性。假设您使用 Maven,您可以将前面的示例重写如下:

info.app.encoding=@project.build.sourceEncoding@
info.app.java.source=@java.version@
info.app.java.target=@java.version@

2.10.3. Git 提交信息

info 端点的另一个有用特性是它能够在项目构建时发布有关 git 源代码存储库状态的信息。如果 GitProperties bean 可用,您可以使用 info 端点来公开这些属性。

如果 git.properties 文件在类路径的根目录可用,则自动配置 GitProperties bean 。请参阅 如何生成 git 信息

默认情况下,端点公开 git.branchgit.commit.idgit.commit.time 属性(如果存在)。如果您不希望端点响应中有任何这些属性,则需要将它们从 git.properties 文件中排除。如果要显示完整的 git 信息(即 git.properties 的完整内容),使用 management.info.git.mode 属性,如下:

management.info.git.mode=full

要完全禁用来自 info 端点的 git 提交信息,请将 management.info.git.enabled 属性设置为 false ,如下所示:

management.info.git.enabled=false

2.10.4. 构建信息

如果 BuildProperties bean 可用,info 端点还可以发布有关您的构建的信息。如果类路径中有 META-INF/build-info.properties 文件可用,则会发生这种情况。

Maven 和 Gradle 插件都可以生成该文件。有关详细信息,请参阅 如何生成构建信息

2.10.5. Java 信息

info 端点发布有关您的 Java 运行时环境的信息,请参阅 JavaInfo

2.10.6. 编写自定义 InfoContributor

要提供自定义应用程序信息,您可以注册实现 InfoContributor 接口的 Spring bean

以下示例提供具有单个值的 example 条目:

import java.util.Collections;

import org.springframework.boot.actuate.info.Info;
import org.springframework.boot.actuate.info.InfoContributor;
import org.springframework.stereotype.Component;

@Component
public class MyInfoContributor implements InfoContributor {

    @Override
    public void contribute(Info.Builder builder) {
        builder.withDetail("example", Collections.singletonMap("key", "value"));
    }

}

如果您访问 info 端点,您应该会看到包含以下额外的条目的响应:

{
    "example": {
        "key" : "value"
    }
}

3. 通过 HTTP 进行监视和管理

如果您正在开发 Web 应用程序,Spring Boot Actuator 会自动配置所有启用的端点以通过 HTTP 公开。默认约定是使用前缀为 /actuator 的 id 端点的作为 URL 路径。例如,health 公开为 /actuator/health

Spring MVC,Spring WebFlux 和 Jersey 原生支持 Actuator 。如果 Jersey 和 Spring MVC 都可用,则使用 Spring MVC

Jackson 是一个必需的依赖项,以获得 API 文档中记录的正确 JSON 响应 ( HTMLPDF )

3.1. 自定义管理端点路径

有时,自定义管理端点的前缀很有用。例如,您的应用程序可能已经将 /actuator 用于其他用途。您可以使用 management.endpoints.web.base-path 属性来更改管理端点的前缀,如以下示例所示:

management.endpoints.web.base-path=/manage

前面的 application.properties 示例将端点从 /actuator/{id} 更改为 /manage/{id}(例如 /manage/info )。

除非管理端口已经被配置为 使用不同的 HTTP 端口公开端点 ,否则 management.endpoints.web.xml-path 相对于 server.servlet.context-path (用于 servlet web 应用程序) 或 spring.webflux.base-path (用于反应式 web 应用程序) 。如果配置了 management.server.port ,那么 management.endpoints.web.xml-path 相对于 management.server.base-path

如果要将端点映射到其他路径,则可以使用 management.endpoints.web.path-mapping 属性。

以下示例重新映射 /actuator/health/healthcheck

management.endpoints.web.base-path=/
management.endpoints.web.path-mapping.health=healthcheck

3.2. 自定义管理服务器端口

对于基于云的部署,通过使用默认的 HTTP 端口公开管理端点是明智的选择。但是,如果您的应用程序在自己的数据中心内运行,则您可能更喜欢使用其他 HTTP 端口公开端点。

您可以设置 management.server.port 属性以更改 HTTP 端口,如以下示例所示:

management.server.port=8081

在 Cloud Foundry 上,默认情况下,应用程序仅在端口 8080上接收HTTP和TCP路由请求。如果要在 Cloud Foundry 上使用自定义管理端口,则需要明确设置应用程序的路由以将流量转发到自定义端口。

3.3. 配置特定于管理的 SSL

当配置为使用自定义端口时,还可以通过使用各种 management.server.ssl.* 属性将管理服务器配置为其自己的 SSL 。例如,这样做可以使管理服务器通过 HTTP 可用,而主应用程序使用 HTTPS ,如以下属性设置所示:

server.port=8443
server.ssl.enabled=true
server.ssl.key-store=classpath:store.jks
server.ssl.key-password=secret
management.server.port=8080
management.server.ssl.enabled=false

或者,主服务器和管理服务器都可以使用 SSL ,但具有不同的密钥存储,如下所示:

server.port=8443
server.ssl.enabled=true
server.ssl.key-store=classpath:main.jks
server.ssl.key-password=secret
management.server.port=8080
management.server.ssl.enabled=true
management.server.ssl.key-store=classpath:management.jks
management.server.ssl.key-password=secret

3.4. 自定义管理服务器地址

您可以通过设置 management.server.address 属性来自定义管理端点可用的地址。如果您只想在内部或面向操作的网络上监听或仅监听来自 localhost 的连接,则这样做很有用。

只有当端口与主服务器端口不同时,您可以在不同的地址监听。

以下 application.properties 示例不允许远程管理连接:

management.server.port=8081
management.server.address=127.0.0.1

3.5. 禁用 HTTP 端点

如果您不想通过 HTTP 公开端点,则可以将管理端口设置为 -1 ,如以下示例所示:

management.server.port=-1

也可以使用 management.endpoints.web.exposure.exclude 属性来实现,如以下示例所示:

management.endpoints.web.exposure.exclude=*

也可以公开所有端点:

management.endpoints.web.exposure.include=*

todo 4. 通过 JMX 进行监视和管理

5. Loggers

Spring Boot Actuator 可以在运行时查看和配置应用程序的日志级别。您可以查看整个列表,也可以查看单个记录器的配置,该配置由显式配置的记录级别以及由日志记录框架赋予它的有效记录级别组成。这些级别可以是以下之一:

  • TRACE
  • DEBUG
  • INFO
  • WARN
  • ERROR
  • FATAL
  • OFF
  • null

null 表示没有显式配置。

5.1. 配置 Logger

要配置给定的 Logger ,POST 请求到资源 URI 的部分实体,如以下示例所示:

{
    "configuredLevel": "DEBUG"
}

要“重置”记录器的特定级别(并使用默认配置),可以传递 null 值给 configuredLevel

示例

例如修改 root 日志级别:

Post 请求,发送 JSON 参数:

http://localhost:8080/actuator/loggers/root

{
    "configuredLevel": "DEBUG"
}

6. 指标(Metrics)

Spring Boot Actuator 为 Micrometer 提供了依赖项管理和自动配置,Micrometer 是一种支持 众多监视系统 的应用程序指标外观,包括:

要了解有关Micrometer功能的更多信息,请参阅其 参考文档 ,特别是 概念部分

6.1. 入门

Spring Boot 自动配置组合 MeterRegistry ,并为其在类路径上找到的每个受支持的实现向组合添加注册。在运行时类路径中具有 micrometer-registry-{system} 依赖项足以让 Spring Boot 配置注册。

大多数注册具有共同的特征。例如,即使 Micrometer 注册实现位于类路径中,您也可以禁用特定的注册。例如,禁用 Datadog

management.metrics.export.datadog.enabled=false

除非特定于注册表的属性另有说明,否则您还可以禁用所有注册表,如以下示例所示:

management.metrics.export.defaults.enabled=false

Spring Boot 还会将任何自动配置的注册添加到 Metrics 类的全局静态复合注册表中,除非您明确告诉它不要:

management.metrics.use-global-registry=false

您可以注册任意数量的 MeterRegistryCustomizer bean 来进一步配置注册表,例如应用通用标签,然后再向注册表注册任何计量器:

import io.micrometer.core.instrument.MeterRegistry;

import org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration(proxyBeanMethods = false)
public class MyMeterRegistryConfiguration {

    @Bean
    public MeterRegistryCustomizer<MeterRegistry> metricsCommonTags() {
        return (registry) -> registry.config().commonTags("region", "us-east-1");
    }

}

您可以通过更具体地了解泛型类型,将自定义项应用于特定的注册表实现:

import io.micrometer.core.instrument.Meter;
import io.micrometer.core.instrument.config.NamingConvention;
import io.micrometer.graphite.GraphiteMeterRegistry;

import org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration(proxyBeanMethods = false)
public class MyMeterRegistryConfiguration {

    @Bean
    public MeterRegistryCustomizer<GraphiteMeterRegistry> graphiteMetricsNamingConvention() {
        return (registry) -> registry.config().namingConvention(this::name);
    }

    private String name(String name, Meter.Type type, String baseUnit) {
        return ...
    }

}

Spring Boot 还配置了您可以通过配置或专用注解标记控制的 内置检测

todo 6.2. 支持的监控系统

  • AppOptics
  • Atlas
  • Datadog
  • Dynatrace
  • Elastic
  • Ganglia
  • Graphite
  • Humio
  • Influx
  • JMX
  • KairosDB
  • New Relic
  • Prometheus
  • SignalFx
  • Simple
  • Stackdriver
  • StatsD
  • Wavefront

todo 6.3. 支持的指标(Metrics)和计量器(Meters)

Spring Boot 为多种技术提供自动计量器注册。在大多数情况下,默认值提供了可以发布到任何受支持的监控系统的合理指标。

  • JVM 指标

    • 各种内存和缓冲池
    • 垃圾回收相关统计
    • 线程利用率
    • 加载和卸载的类数
  • 系统指标

    • CPU 指标
    • 文件描述符指标
    • 正常运行时间指标(应用程序运行的时间量和绝对启动时间的固定指标)
    • 可用磁盘空间
  • 应用程序启动指标

    • application.started.time : 启动应用程序所用的时间。
    • application.ready.time :应用程序准备好为请求提供服务所需的时间。
  • 记录器指标

  • 任务执行和调度指标

  • Spring MVC 指标

  • Spring WebFlux 指标

  • Jersey 服务器指标

  • HTTP Client 指标

  • Tomcat 指标

  • 缓存指标

  • 数据源指标

  • Hibernate 指标

  • Spring Data 存储库指标

  • RabbitMQ 指标

  • Spring Integration 指标

  • Kafka 指标

  • MongoDB 指标

  • Jetty 指标

  • @Timed 注解支持

  • Redis 指标

6.4. 注册自定义指标

要注册自定义指标,请注入 MeterRegistry 到您的组件中,如以下示例所示:

import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Tags;

import org.springframework.stereotype.Component;

@Component
public class MyBean {

    private final Dictionary dictionary;

    public MyBean(MeterRegistry registry) {
        this.dictionary = Dictionary.load();
        registry.gauge("dictionary.size", Tags.empty(), this.dictionary.getWords().size());
    }

}

如果您的指标依赖于其他 bean,我们建议您使用 MeterBinder 来注册它们:

import io.micrometer.core.instrument.Gauge;
import io.micrometer.core.instrument.binder.MeterBinder;

import org.springframework.context.annotation.Bean;

public class MyMeterBinderConfiguration {

    @Bean
    public MeterBinder queueSize(Queue queue) {
        return (registry) -> Gauge.builder("queueSize", queue::size).register(registry);
    }

}

使用 MeterBinder 可确保设置正确的依赖关系,并且在检索度量值时 bean 可用。如果您发现您反复检测跨组件或应用程序的一组指标,则 MeterBinder 实现也可能很有用。

默认情况下,来自所有 MeterBinder bean 的指标会自动绑定到 Spring 管理的 MeterRegistry

6.5. 自定义单个指标

如果需要将自定义应用于特定 Meter 实例,可以使用 io.micrometer.core.instrument.config.MeterFilter 接口。

例如,如果要将所有以 com.example 开头的计量器 ID 的 mytag.region 标签重命名为 mytag.area ,则可以执行以下操作:

import io.micrometer.core.instrument.config.MeterFilter;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration(proxyBeanMethods = false)
public class MyMetricsFilterConfiguration {

    @Bean
    public MeterFilter renameRegionTagMeterFilter() {
        return MeterFilter.renameTag("com.example", "mytag.region", "mytag.area");
    }

}

默认情况下,所有 MeterFilter bean 都自动绑定到 Spring 管理的 MeterRegistry 。确保使用 Spring 管理的 MeterRegistry 而不是 Metrics 上的任何静态方法来注册您的指标。这些使用非 Spring 管理的全局注册表。

6.5.1. 通用标签

通用标签通常用于在操作环境(如主机,实例,区域,堆栈等)上进行维度深入分析。通用标签适用于所有计量器,并可以按以下示例所示进行配置:

management.metrics.tags.region=us-east-1
management.metrics.tags.stack=prod

上面的示例将 regionstack 标记分别添加到具有 us-east-1prod 的值的所有计量器。

如果使用 Graphite ,则通用标签的顺序很重要。由于使用这种方法不能保证通用标签的顺序,因此建议 Graphite 用户定义一个自定义 MeterFilter

6.5.2. Per-meter 属性

除了 MeterFilter bean ,还可以使用属性在 per-meter 的基础上应用一组有限的自定义设置。per-meter 自定义适用于以给定名称开头的所有计量器 ID 。例如,以下将禁用所有以 example.remote 开头的计量器 ID

management.metrics.enable.example.remote=false

以下属性允许按 per-meter 自定义:

属性 描述
management.metrics.enable 是否阻止计量器发出任何指标
management.metrics.distribution.percentiles-histogram 是否发布适合计算可聚合(跨维度)百分位近似值的直方图
management.metrics.distribution.minimum-expected-value
management.metrics.distribution.maximum-expected-value
通过限制期望值的范围来发布较少的直方图桶
management.metrics.distribution.percentiles 发布在您的应用程序中计算的百分位数
management.metrics.distribution.expiry
management.metrics.distribution.buffer-length
通过在可配置的到期后旋转的环形缓冲区中累积最近的样本,赋予它们更大的权重,并具有可配置的缓冲区长度
management.metrics.distribution.slo 发布包含由您的服务级别目标定义的存储桶的累积直方图

有关 percentiles-histogrampercentilessla 的更多细节,请参阅 “Histograms and percentiles” section

6.6. 指标端点

Spring Boot 提供了一个metrics端点,可用于诊断检查应用程序收集的指标。端点默认情况下不可用,必须公开。

导航 /actuator/metrics 显示可用仪表名称的列表。您可以通过提供特定的仪表名称作为选择器来向下浏览以查看有关该仪表的信息,例如 /actuator/metrics/jvm.memory.max

您在此处使用的名称应与代码中使用的名称相匹配,而不是将其作为监控系统的标准化命名约定后的名称。换句话说,如果 jvm.memory.max 在 Prometheus 中显示为 jvm memory max ,因为它的变数命名原则是蛇形的,那么在检查指标端点的计量器时,仍然应该使用 jvm.memory.max 作为选择器。

您还可以在 URL 的末尾添加任意数量的 tag=KEY:VALUE 查询参数,以在维度上进一步细分计量器,例如 /actuator/metrics/jvm.memory.max?tag=area:nonheap

报告的测量值是与计量器名称和已应用的任何标签相匹配的所有计量器的统计信息的总和。因此,在上面的示例中,返回的“值”统计量是堆的“代码缓存”,“压缩类空间”和“元空间”区域的最大内存占用量的总和。如果您只想查看 Metaspace 的最大大小,则可以添加一个额外的 tag=id:Metaspace ,即 /actuator/metrics/jvm.memory.max?tag=area:nonheap&tag=id:Metaspace

7. 审计(Auditing)

一旦 Spring Security 发挥作用,Spring Boot Actuator 将拥有一个灵活的审计框架来发布事件(默认情况下,“身份验证成功”,“失败”和“拒绝访问”异常)。此功能对于基于身份验证失败的报告和实施锁定策略非常有用。

可以通过在应用程序的配置中提供 AuditEventRepository 类型的 bean 来启用审计。为了方便起见,Spring Boot 提供了 InMemoryAuditEventRepositoryInMemoryAuditEventRepository 功能有限,我们建议仅将其用于开发环境。对于生产环境,请考虑创建自己的替代 AuditEventRepository 实现。

7.1. 自定义审计

要自定义已发布的安全事件,可以提供自己的 AbstractAuthenticationAuditListenerAbstractAuthorizationAuditListener 实现。

您也可以将审计服务用于自己的业务事件。为此,可以将 AuditEventRepository bean 注入您自己的组件中,然后直接使用它,也可以使用 Spring ApplicationEventPublisher 发布 AuditApplicationEvent (通过实现 ApplicationEventPublisherAware )。

8. HTTP 跟踪(HTTP Tracing)

可以通过在应用程序的配置中提供 HttpTraceRepository 类型的 bean 来启用 HTTP 跟踪。为了方便起见,Spring Boot 提供了一个默认存储最后 100个 请求-响应交换的跟踪的 InMemoryHttpTraceRepositoryInMemoryHttpTraceRepository 与其他跟踪解决方案相比,它受到限制,我们建议仅将其用于开发环境。对于生产环境,建议使用可用于生产的跟踪或可观察性解决方案,例如 Zipkin 或 Spring Cloud Sleuth 。或者,创建自己的 HttpTraceRepository

httptrace 端点可以被用来获得关于被存储在 HttpTraceRepository 中的请求-响应交换信息。

8.1. 自定义 HTTP 跟踪

要自定义每个跟踪中包含的项目,请使用 management.trace.http.include 配置属性。对于高级定制,请考虑注册自己的 HttpExchangeTracer 实现。

9. 过程监控(Process Monitoring)

spring-boot 模块中,您可以找到两个类来创建通常对进程监控有用的文件:

  • ApplicationPidFileWriter 创建一个包含应用程序PID的文件(默认情况下,在应用程序目录中的文件名为 application.pid
  • WebServerPortFileWriter 创建一个文件(一个或多个),其中包含正在运行的 Web 服务器的端口(默认情况下,在应用程序目录中,文件名为 application.port )。

默认情况下,不会激活这些类,但是您可以通过以下方式启用:

9.1. 扩展配置

META-INF/spring.factories 文件中,您可以激活写入 PID 文件的监听器,如以下示例所示:

org.springframework.context.ApplicationListener=\
org.springframework.boot.context.ApplicationPidFileWriter,\
org.springframework.boot.web.context.WebServerPortFileWriter

9.2. 以编程方式启用过程监控

您也可以通过调用 SpringApplication.addListeners(..) 方法并传递适当的 Writer 对象来激活监听器。此方法还允许您自定义 Writer 构造函数中的文件名和路径。

10. Cloud Foundry 支持

Spring Boot 的执行器模块包括额外的支持,当您将其部署到兼容的 Cloud Foundry 实例时就会激活。/cloudfoundryapplication 路径提供了通往所有 @Endpoint bean 的替代安全路由。

扩展支持使 Cloud Foundry 管理 UI(例如可用于查看已部署的应用程序的 Web 应用程序)增加了 Spring Boot 执行器信息。例如,应用程序状态页面可能包含完整的运行状况信息,而不是典型的 runningstopped 状态。

普通用户不能直接访问 /cloudfoundryapplication 路径。要使用端点,您必须在请求中传递有效的 UAA 令牌。

10.1. 禁用扩展的 Cloud Foundry 执行器支持

如果要完全禁用 /cloudfoundryapplication 端点,可以将以下设置添加到 application.properties 文件中:

management.cloudfoundry.enabled=false

10.2. Cloud Foundry 自签名证书

默认情况下,/cloudfoundryapplication 端点的安全性验证会对各种 Cloud Foundry 服务进行 SSL 调用。如果您的 Cloud Foundry UAA 或 Cloud Controller 服务使用自签名证书,则需要设置以下属性:

management.cloudfoundry.skip-ssl-validation=true

10.3. 自定义上下文路径

如果服务器的上下文路径已配置为 / 以外的任何其他值,则 Cloud Foundry 端点在应用程序的根目录将不可用。例如,如果 server.servlet.context-path=/app ,Cloud Foundry 端点将可用 /app/cloudfoundryapplication/*

如果您希望 Cloud Foundry 端点始终在 /cloudfoundryapplication/* 处可用,而与服务器的上下文路径无关,则需要在应用程序中进行显式配置。配置将根据所使用的 Web 服务器而有所不同。对于 Tomcat ,可以添加以下配置:

import java.io.IOException;
import java.util.Collections;

import javax.servlet.GenericServlet;
import javax.servlet.Servlet;
import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.apache.catalina.Host;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.startup.Tomcat;

import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration(proxyBeanMethods = false)
public class MyCloudFoundryConfiguration {

    @Bean
    public TomcatServletWebServerFactory servletWebServerFactory() {
        return new TomcatServletWebServerFactory() {

            @Override
            protected void prepareContext(Host host, ServletContextInitializer[] initializers) {
                super.prepareContext(host, initializers);
                StandardContext child = new StandardContext();
                child.addLifecycleListener(new Tomcat.FixContextListener());
                child.setPath("/cloudfoundryapplication");
                ServletContainerInitializer initializer = getServletContextInitializer(getContextPath());
                child.addServletContainerInitializer(initializer, Collections.emptySet());
                child.setCrossContext(true);
                host.addChild(child);
            }

        };
    }

    private ServletContainerInitializer getServletContextInitializer(String contextPath) {
        return (classes, context) -> {
            Servlet servlet = new GenericServlet() {

                @Override
                public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
                    ServletContext context = req.getServletContext().getContext(contextPath);
                    context.getRequestDispatcher("/cloudfoundryapplication").forward(req, res);
                }

            };
            context.addServlet("cloudfoundry", servlet).addMapping("/*");
        };
    }

}
posted @ 2022-06-08 07:59  流星<。)#)))≦  阅读(102)  评论(0编辑  收藏  举报