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.file 或loggin.path 属性已经设置了),支持使用HTTP Range header来检索日志文件内容的一部分 | Yes |
prometheus | 公开指标,该格式可以被Prometheus服务器采集 | Yes |
要了解有关Actuator的端点及其请求和响应格式的更多信息,请参考单独的API文档(HTML 或 PDF)。
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
禁用的端点完全从应用程序上下文中删除,如果你只想更改端点暴露的技术,则使用
include
和
exclude
属性代替。
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 |
要更改公开的端点,请使用以下技术特定的include
和exclude
属性:
属性 | 默认 |
---|---|
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
属性,include
和exclude
属性都可以使用端点id列表进行配置。
例如,要停止在JMX上公开所有端点,并且只公开health
和info
端点,请使用以下属性:
management.endpoints.jmx.exposure.include=health,info
*
可用于选择所有端点,例如,要通过HTTP公开除env
和beans
端点之外的所有内容,请使用以下属性:
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文档(HTML 或 PDF)。
如果你将应用程序部署到防火墙后,你可能希望可以在不需要身份验证的情况下访问所有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域GET
和POST
调用:
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
属性确定,属性是可选的,如果不使用,则自动确定“生成”子句。
如果操作方法返回void
或Void
,则生成子句为空,如果操作方法返回一个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.Principal
或org.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中自动配置:
- 检查Cassandra数据库是否已启动
- 检查低磁盘空间
- 检查能否获得到
DataSource
的连接
- 检查Elasticsearch集群是否已启动
- 检查InfluxDB服务是否已启动
- 检查JMS代理是否已启动
- 检查邮件服务是否已启动
- 检查Mongo数据库是否已启动
- 检查Neo4j服务是否已经启动
- 检查Rabbit服务是否已经启动
- 检查Redis服务是否已启动
- 检查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_SERVICE
和DOWN
映射到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