5

50. 端点

Actuator端点让你监视和与应用程序交互,Spring Boot包含许多内置的端点,并允许你添加自己的端点。例如,health端点提供基本的应用程序健康信息。

可以启用或禁用每个单独的端点,这将控制端点是否被创建,以及它的bean是否存在于应用程序上下文中,要实现远程访问,端点还必须通过JMX或HTTP公开,大多数应用程序选择HTTP,将端点的ID与/actuator的前缀映射到URL。例如,默认情况下,health端点映射到/actuator/health

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

ID 描述 默认启用
auditevents 公开当前应用程序的审计事件信息 Yes
beans 显示应用程序中所有Spring bean的完整列表 Yes
conditions 显示在配置和自动配置类上评估的条件以及它们是否匹配的原因 Yes
configprops 显示所有@ConfigurationProperties对照的列表 Yes
env 从Spring的ConfigurableEnvironment中公开属性 Yes
flyway 显示已应用的任何Flyway数据库迁移 Yes
health 显示应用程序健康信息 Yes
httptrace 显示HTTP跟踪信息(默认情况下,最后100个HTTP请求-响应交互) Yes
info 显示任意应用程序信息 Yes
loggers 显示和修改应用程序中记录器的配置 Yes
liquibase 显示已应用的任何Liquibase数据库迁移 Yes
metrics 显示当前应用程序的“指标”信息 Yes
mappings 显示所有@RequestMapping路径对照的列表 Yes
scheduledtasks 显示应用程序中调度的任务 Yes
sessions 允许从Spring session支持的会话存储中检索和删除用户会话,在使用Spring会话对响应性web应用程序的支持时不可用 Yes
shutdown 让应用程序优雅地关闭 No
threaddump 执行线程转储 Yes

如果你的应用程序是一个web应用程序(Spring MVC、Spring WebFlux或Jersey),你可以使用以下附加端点:

ID 描述 默认启用
heapdump 返回一个GZip压缩的hprof堆转储文件 Yes
jolokia 在HTTP上公开JMX bean(当Jolokia在类路径上时,WebFlux不可用) Yes
logfile 返回日志文件的内容(如果是logging.fileloggin.path属性已经设置了),支持使用HTTP Range header来检索日志文件内容的一部分 Yes
prometheus 公开指标,该格式可以被Prometheus服务器采集 Yes

要了解有关Actuator的端点及其请求和响应格式的更多信息,请参考单独的API文档(HTMLPDF)。

50.1 启用端点

默认情况下,除了shutdown之外的所有端点都启用了,要配置端点的启动,可以使用它的management.endpoint.<id>.enabled属性,下面的示例启用关闭端点:

management.endpoint.shutdown.enabled=true

如果你更喜欢端点opt-in而不是opt-out,设置management.endpoints.enabled-by-default属性为false并使用单独的端点启用属性来选择返回,下面的示例启用info端点并禁用所有其他端点:

management.endpoints.enabled-by-default=false
management.endpoint.info.enabled=true
禁用的端点完全从应用程序上下文中删除,如果你只想更改端点暴露的技术,则使用includeexclude属性代替。

50.2 公开端点

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

ID JMX Web
auditevents Yes No
beans 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 Yes
jolokia N/A No
logfile N/A No
loggers Yes No
liquibase Yes No
metrics Yes No
mappings Yes No
prometheus N/A No
scheduledtasks Yes No
sessions Yes No
shutdown Yes No
threaddump Yes No

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

属性 默认
management.endpoints.jmx.exposure.exclude
management.endpoints.jmx.exposure.include *
management.endpoints.web.exposure.exclude
management.endpoints.web.exposure.include info, health

include属性列出了公开的端点的id,exclude属性列出不应公开的端点的id,exclude属性优先于include属性,includeexclude属性都可以使用端点id列表进行配置。

例如,要停止在JMX上公开所有端点,并且只公开healthinfo端点,请使用以下属性:

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

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

management.endpoints.web.exposure.include=*
management.endpoints.web.exposure.exclude=env,beans
*在YAML中有特殊的含义,所以如果要包含(或排除)所有端点,请务必添加引号,如下例所示:
management:
  endpoints:
    web:
      exposure:
        include: "*"
如果你的应用程序是对外公开的,我们强烈建议你也保护你的端点。

如果你想要当端点暴露时实现自己的策略,可以注册EndpointFilter bean。

50.3 HTTP端点安全

你应该注意保护HTTP端点的方式,就像保护其他敏感URL一样,如果存在Spring Security,则使用Spring Security的内容协商策略默认保护端点。如果你希望为HTTP端点配置自定义安全性,例如,只允许具有特定角色的用户访问它们,Spring Boot提供了一些方便的RequestMatcher对象,可以与Spring Security结合使用。

一个典型的Spring安全配置可能如下面的示例所示:

@Configuration
public class ActuatorSecurity extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeRequests()
                .anyRequest().hasRole("ENDPOINT_ADMIN")
                .and()
            .httpBasic();
    }

}

前面的示例使用EndpointRequest.toAnyEndpoint()匹配任何端点的请求,然后确保所有端点都具有ENDPOINT_ADMIN角色,在EndpointRequest上还有几个其他的matcher方法,详情请参阅API文档(HTMLPDF)。

如果你将应用程序部署到防火墙后,你可能希望可以在不需要身份验证的情况下访问所有actuator端点,你可以通过更改management.endpoints.web.exposure.include属性来实现这一点,如下:

application.properties

management.endpoints.web.exposure.include=*

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

@Configuration
public class ActuatorSecurity extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeRequests()
            .anyRequest().permitAll()
    }

}

50.4 配置端点

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

application.properties

management.endpoint.beans.cache.time-to-live=10s
前缀management.endpoint.<name>用于惟一地标识正在配置的端点。

在发出经过身份验证的HTTP请求时,Principal被认为是端点的输入,因此不会缓存响应。

50.5 Actuator Web端点的超媒体

一个链接所有端点的“discovery页面”被添加,默认情况下,“ discovery页面”在/actuator上可用。

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

50.6 Actuator Web端点的路径

默认情况下,通过使用端点的ID在/actuator路径下通过HTTP公开端点,例如,beans端点在/actuator/beans下公开,如果希望将端点映射到不同的路径,可以使用management.endpoints.web.path-mapping属性,另外,如果你想要更改基本路径,你可以使用management.endpoints.web.base-path

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

application.properties

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

50.7 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=http://example.com
management.endpoints.web.cors.allowed-methods=GET,POST
有关选项的完整列表,请参见CorsEndpointProperties

50.8 实现自定义端点

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

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

可以使用@EndpointWebExtension@EndpointJmxExtension编写特定于技术的扩展,这些注解允许你提供特定于技术的操作,以增强现有的端点。

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

50.8.1 接收输入

端点上的操作通过它们的参数接收输入,当通过web公开时,这些参数的值取自URL的查询参数和JSON请求体,当通过JMX公开时,参数被映射到MBean操作的参数,默认情况下需要参数,可以使用@org.springframework.lang.Nullable对它们进行注解,从而使它们成为可选的。

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

输入类型转换

如果需要,传递给端点操作方法的参数将自动转换为所需的类型,在调用操作方法之前,使用ApplicationConversionService实例将通过JMX或HTTP请求接收的输入转换为所需的类型。

50.8.2 自定义Web端点

@Endpoint@WebEndpoint@WebEndpointExtension的操作通过使用Jersey、Spring MVC或Spring WebFlux通过HTTP自动公开。

Web端点请求谓词

在web公开的端点上,每个操作都会自动生成一个请求谓词。

路径

谓词的路径由端点的ID和web公开端点的基本路径决定,默认的基本路径是/actuator,例如,具有ID sessions的端点将在谓词中使用/actuator/sessions作为其路径。

通过使用@Selector注解操作方法的一个或多个参数,可以进一步定制路径,这样的参数作为路径变量添加到路径谓词,当调用端点操作时,将变量的值传递给操作方法。

HTTP方法

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

  • @ReadOperation => GET
  • @WriteOperation => POST
  • @DeleteOperation => DELETE
消费

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

生产

谓词的生产子句可以由@DeleteOperation@ReadOperation@WriteOperation注解的produces属性确定,属性是可选的,如果不使用,则自动确定“生成”子句。

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

Web端点响应状态

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

@ReadOperation返回一个值,响应状态为200 (OK),如果不返回值,响应状态将为404(Not Found)。

如果@WriteOperation@DeleteOperation返回一个值,则响应状态为200 (OK),如果不返回值,响应状态将为204(No Content)。

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

Web端点范围请求

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

使用Jersey时不支持范围请求
Web端点安全

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

50.8.3 Servlet端点

Servlet可以通过实现一个带有@ServletEndpoint注解的类来作为端点公开,这个类也实现了Supplier<EndpointServlet>。Servlet端点提供了与Servlet容器更深层次的集成,但暴露了可移植性,它们用于将现有的Servlet公开为端点。对于新的端点,应该尽可能使用@Endpoint@WebEndpoint注解。

50.8.4 Controller端点

可以使用@ControllerEndpoint@RestControllerEndpoint实现仅由Spring MVC或Spring WebFlux公开的端点,方法使用Spring MVC和Spring WebFlux(如@RequestMapping@GetMapping)的标准注解进行映射,使用端点的ID作为路径的前缀。Controller端点提供了与Spring web框架的更深入的集成,但却牺牲了可移植性,尽可能使用@Endpoint和@WebEndpoint注解。

50.9 健康信息

你可以使用健康信息检查正在运行的应用程序的状态,当生产系统崩溃时,监控软件通常会用它来通知某人,health端点公开的信息取决于management.endpoint.health.show-details属性,可以使用以下值之一配置:

never

  • 不显示细节

when-authorized

  • 详细信息只显示给授权用户,可以使用management.endpoint.health.roles配置授权角色

always

  • 详细信息显示给所有用户

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

如果你已经保护了你的应用程序并且希望使用always,你的安全配置必须允许对经过身份验证的用户和未经身份验证的用户访问健康端点。

健康信息是从你的ApplicationContext中定义的所有HealthIndicator bean中收集的,Spring Boot包括许多自动配置的HealthIndicators,并且你也可以自己写。默认情况下,最终的系统状态由HealthAggregator派生,它根据有序的状态列表从每个HealthIndicator排序状态。排序列表中的第一个状态被用作总体健康状态,如果没有HealthAggregator所知道的HealthIndicator状态返回,则使用UNKNOWN状态。

50.9.1 自动配置HealthIndicators

以下的HealthIndicators在适当的时候在Spring Boot中自动配置:

CassandraHealthIndicator

  • 检查Cassandra数据库是否已启动

DiskSpaceHealthIndicator

  • 检查低磁盘空间

DataSourceHealthIndicator

  • 检查能否获得到DataSource的连接

ElasticsearchHealthIndicator

  • 检查Elasticsearch集群是否已启动

InfluxDbHealthIndicator

  • 检查InfluxDB服务是否已启动

JmsHealthIndicator

  • 检查JMS代理是否已启动

MailHealthIndicator

  • 检查邮件服务是否已启动

MongoHealthIndicator

  • 检查Mongo数据库是否已启动

Neo4jHealthIndicator

  • 检查Neo4j服务是否已经启动

RabbitHealthIndicator

  • 检查Rabbit服务是否已经启动

RedisHealthIndicator

  • 检查Redis服务是否已启动

SolrHealthIndicator

  • 检查Solr服务是否已启动
你可以通过设置management.health.defaults.enabled属性来禁用它们所有。

50.9.2 编写自定义HealthIndicators

要提供自定义的健康信息,你可以注册实现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(); // perform some specific health check
        if (errorCode != 0) {
            return Health.down().withDetail("Error Code", errorCode).build();
        }
        return Health.up().build();
    }

}
给定HealthIndicator的标识符是没有HealthIndicator后缀的bean的名称(如果存在的话),在前面的示例中,健康信息可以在名为my的条目中获得。

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

例如,假设在你的一个HealthIndicator实现中使用了一个带有代码FATAL的新Status,要配置严重性顺序,请在应用程序属性中添加以下属性:

management.health.status.order=FATAL, DOWN, OUT_OF_SERVICE, UNKNOWN, UP

响应中的HTTP状态代码反映总体健康状态(例如,UP映射到200,而OUT_OF_SERVICEDOWN映射到503),如果你通过HTTP访问健康端点,你可能还想注册自定义状态映射,例如,以下属性将FATAL映射到503(service unavailable):

management.health.status.http-mapping.FATAL=503
如果你需要更多的控制,你可以定义自己的HealthStatusHttpMapper bean。

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

DOWN

  • SERVICE_UNAVAILABLE (503)

OUT_OF_SERVICE

  • SERVICE_UNAVAILABLE (503)

UP

  • 默认情况下没有映射,所以http状态是200

UNKNOWN

  • 默认情况下没有映射,所以http状态是200

50.9.3 Reactive健康指标


上一篇:启用生产就绪特性
下一篇:通过HTTP监控和管理

博弈
2.5k 声望1.5k 粉丝

态度决定一切