Spring Boot 包含许多额外功能,帮助您在将应用推送到生产环境时进行监控和管理。您可以选择使用 HTTP 端点或 JMX 来管理和监控应用程序。审计、健康状况和指标收集也可以自动应用于您的应用程序。
1. 启用生产就绪功能
spring-boot-actuator
模块提供了 Spring Boot 的所有生产就绪功能。启用这些功能的推荐方法是在 spring-boot-starter-actuator
“Starter” 上添加依赖。
要将 Actuator 添加到基于 Maven 的项目中,请添加以下“Starter”依赖项:
<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. 端点
执行器端点允许您监视和与应用程序交互。Spring Boot包含许多内置端点,并允许您添加自己的端点。例如,health
端点提供基本的应用程序健康信息。
您可以启用或禁用每个单独的端点,并且可以公开它们(使它们可以通过HTTP或JMX远程访问)。只有在端点启用和公开时,端点才被视为可用。内置端点仅在可用时自动配置。大多数应用程序选择通过HTTP公开,其中端点的ID和/actuator
前缀映射到URL。例如,默认情况下,health
端点映射到/actuator/health
。
以下与技术无关的端点可用:
ID | 描述 |
---|---|
|
公开当前应用程序的审计事件信息。需要一个 |
|
显示应用程序中所有Spring bean的完整列表。 |
|
公开可用的缓存。 |
|
显示在配置和自动配置类上评估的条件以及它们匹配或不匹配的原因。 |
|
显示所有 |
|
公开Spring的 |
|
显示已应用的任何Flyway数据库迁移。需要一个或多个 |
|
显示应用程序健康信息。 |
|
显示HTTP交换信息(默认情况下,显示最后100个HTTP请求-响应交换)。需要一个 |
|
显示任意应用程序信息。 |
|
显示Spring集成图。需要依赖于 |
|
显示并修改应用程序中日志记录器的配置。 |
|
显示已应用的任何Liquibase数据库迁移。需要一个或多个 |
|
显示当前应用程序的“度量”信息。 |
|
显示所有 |
|
显示有关Quartz Scheduler作业的信息。受到消毒的影响。 |
|
显示应用程序中的定时任务。 |
|
允许从基于Spring Session的会话存储中检索和删除用户会话。需要使用Spring Session的基于Servlet的Web应用程序。 |
|
允许应用程序优雅关闭。仅在使用jar打包时有效。默认情况下禁用。 |
|
显示由 |
|
执行线程转储。 |
如果您的应用程序是Web应用程序(Spring MVC、Spring WebFlux或Jersey),您可以使用以下附加端点:
ID | 描述 |
---|---|
|
返回堆转储文件。在HotSpot JVM上,返回一个 |
|
返回日志文件的内容(如果已设置 |
|
以可被Prometheus服务器抓取的格式公开指标。需要依赖于 |
2.1. 启用端点
默认情况下,除了shutdown
端点外,所有端点都是启用的。要配置端点的启用情况,请使用其management.endpoint.<id>.enabled
属性。以下示例启用了shutdown
端点:
management.endpoint.shutdown.enabled=true
management:
endpoint:
shutdown:
enabled: true
如果您更喜欢端点的启用是选择加入而不是选择退出,请将management.endpoints.enabled-by-default
属性设置为false
,并使用单独的端点enabled
属性选择重新加入。以下示例启用了info
端点并禁用了所有其他端点:
management.endpoints.enabled-by-default=false
management.endpoint.info.enabled=true
management:
endpoints:
enabled-by-default: false
endpoint:
info:
enabled: true
禁用的端点将完全从应用程序上下文中删除。如果您只想更改端点公开的技术,请改用include 和exclude 属性。 |
2.2. 公开端点
默认情况下,只有健康端点通过HTTP和JMX公开。由于端点可能包含敏感信息,您应仔细考虑何时公开它们。
要更改公开哪些端点,请使用以下特定于技术的include
和exclude
属性:
属性 | 默认值 |
---|---|
|
|
|
|
|
|
|
|
include
属性列出了要公开的端点的ID。 exclude
属性列出了不应公开的端点的ID。 exclude
属性优先于include
属性。您可以使用端点ID列表配置include
和exclude
属性。
例如,要仅通过JMX公开health
和info
端点,请使用以下属性:
management.endpoints.jmx.exposure.include=health,info
management:
endpoints:
jmx:
exposure:
include: "health,info"
*
可用于选择所有端点。例如,要通过HTTP公开所有内容,除了env
和beans
端点,请使用以下属性:
management.endpoints.web.exposure.include=*
management.endpoints.web.exposure.exclude=env,beans
management:
endpoints:
web:
exposure:
include: "*"
exclude: "env,beans"
* 在YAML中具有特殊含义,因此如果要包含(或排除)所有端点,请确保添加引号。 |
如果您的应用程序是公开的,强烈建议您也保护您的端点。 |
如果您想要实现自己的端点公开策略,可以注册一个EndpointFilter bean。 |
2.3. 安全性
出于安全目的,默认情况下只有 /health
端点通过HTTP公开。您可以使用 management.endpoints.web.exposure.include
属性配置要公开的端点。
在设置 management.endpoints.web.exposure.include 之前,请确保公开的执行器不包含敏感信息,通过将它们放在防火墙后面进行保护,或者通过类似于Spring Security的方式进行保护。 |
如果类路径上存在Spring Security并且没有其他 SecurityFilterChain
bean,除了 /health
之外的所有执行器都将由Spring Boot自动配置进行安全保护。如果定义了自定义的 SecurityFilterChain
bean,则Spring Boot自动配置会退出,并允许您完全控制执行器访问规则。
如果您希望为HTTP端点配置自定义安全性(例如,只允许具有特定角色的用户访问它们),Spring Boot提供了一些方便的 RequestMatcher
对象,您可以与Spring Security结合使用。
典型的Spring Security配置可能如下所示:
@Configuration(proxyBeanMethods = false)
public class MySecurityConfiguration {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.securityMatcher(EndpointRequest.toAnyEndpoint());
http.authorizeHttpRequests((requests) -> requests.anyRequest().hasRole("ENDPOINT_ADMIN"));
http.httpBasic(withDefaults());
return http.build();
}
}
@Configuration(proxyBeanMethods = false)
class MySecurityConfiguration {
@Bean
fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
http.securityMatcher(EndpointRequest.toAnyEndpoint()).authorizeHttpRequests { requests ->
requests.anyRequest().hasRole("ENDPOINT_ADMIN")
}
http.httpBasic(withDefaults())
return http.build()
}
}
上述示例使用 EndpointRequest.toAnyEndpoint()
来匹配任何端点的请求,然后确保所有端点都具有 ENDPOINT_ADMIN
角色。 EndpointRequest
还提供了其他几种匹配方法。有关详细信息,请参阅API文档(HTML 或 PDF)。
如果将应用程序部署在防火墙后面,您可能希望所有执行器端点都可以在不需要身份验证的情况下访问。您可以通过更改 management.endpoints.web.exposure.include
属性来实现:
management.endpoints.web.exposure.include=*
management:
endpoints:
web:
exposure:
include: "*"
此外,如果存在Spring Security,您需要添加自定义安全配置,以允许未经身份验证访问端点,如下例所示:
@Configuration(proxyBeanMethods = false)
public class MySecurityConfiguration {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.securityMatcher(EndpointRequest.toAnyEndpoint());
http.authorizeHttpRequests((requests) -> requests.anyRequest().permitAll());
return http.build();
}
}
@Configuration(proxyBeanMethods = false)
class MySecurityConfiguration {
@Bean
fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
http.securityMatcher(EndpointRequest.toAnyEndpoint()).authorizeHttpRequests { requests ->
requests.anyRequest().permitAll()
}
return http.build()
}
}
在上述两个示例中,配置仅适用于执行器端点。由于Spring Boot的安全配置在存在任何 SecurityFilterChain bean 时完全退出,您需要配置一个额外的 SecurityFilterChain bean,其中包含适用于应用程序其余部分的规则。 |
2.3.1. 跨站请求伪造保护
由于Spring Boot依赖于Spring Security的默认设置,默认情况下启用了CSRF保护。这意味着在使用默认安全配置时,需要 POST
(关闭和日志记录器端点)、PUT
或 DELETE
的执行器端点会收到403(禁止)错误。
我们建议仅在创建供非浏览器客户端使用的服务时完全禁用CSRF保护。 |
您可以在 Spring Security参考指南 中找到有关CSRF保护的其他信息。
2.4. 配置端点
端点会自动缓存不带任何参数的读操作的响应。要配置端点缓存响应的时间,请使用其 cache.time-to-live
属性。以下示例将 beans
端点的缓存存活时间设置为10秒:
management.endpoint.beans.cache.time-to-live=10s
management:
endpoint:
beans:
cache:
time-to-live: "10s"
management.endpoint.<name> 前缀唯一标识正在配置的端点。 |
2.5. 敏感值的清理
默认情况下,/env
、/configprops
和/quartz
端点返回的信息可能是敏感的,因此值始终会被完全清理(替换为******
)。
只有在以下情况下才能以未经清理的形式查看值:
-
已将
show-values
属性设置为除NEVER
之外的其他值 -
没有自定义的
SanitizingFunction
bean应用
可以将show-values
属性配置为以下值之一,以用于可清理的端点:
-
NEVER
- 值始终被完全清理(替换为******
) -
ALWAYS
- 值向所有用户显示(只要没有SanitizingFunction
bean应用) -
WHEN_AUTHORIZED
- 值仅向授权用户显示(只要没有SanitizingFunction
bean应用)
对于HTTP端点,如果用户已经进行了身份验证并具有端点角色属性配置的角色,则认为用户已被授权。默认情况下,任何经过身份验证的用户都被授权。
对于JMX端点,所有用户始终被授权。
以下示例允许所有具有admin
角色的用户以原始形式查看/env
端点的值。未经授权的用户或没有admin
角色的用户将只能看到清理后的值。
management.endpoint.env.show-values=WHEN_AUTHORIZED
management.endpoint.env.roles=admin
management:
endpoint:
env:
show-values: WHEN_AUTHORIZED
roles: "admin"
此示例假定未定义任何SanitizingFunction bean。 |
2.6. Actuator Web端点的超媒体
添加了一个“发现页面”,其中包含到所有端点的链接。默认情况下,“发现页面”位于/actuator
上。
要禁用“发现页面”,请将以下属性添加到应用程序属性中:
management.endpoints.web.discovery.enabled=false
management:
endpoints:
web:
discovery:
enabled: false
当配置了自定义管理上下文路径时,“发现页面”会自动从/actuator
移动到管理上下文的根路径。例如,如果管理上下文路径为/management
,则发现页面可从/management
访问。当管理上下文路径设置为/
时,将禁用发现页面,以防止与其他映射发生冲突。
2.7. 跨源资源共享(CORS)支持
CORS支持默认情况下是禁用的,只有在设置了management.endpoints.web.cors.allowed-origins
属性后才会启用。以下配置允许example.com
域中的GET
和POST
调用:
management.endpoints.web.cors.allowed-origins=https://example.com
management.endpoints.web.cors.allowed-methods=GET,POST
management:
endpoints:
web:
cors:
allowed-origins: "https://example.com"
allowed-methods: "GET,POST"
请参阅完整选项列表:CorsEndpointProperties |
2.8. 实现自定义端点
如果您添加一个使用@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);
}
@ReadOperation
fun getData(): CustomData {
return CustomData("test", 5)
}
您还可以通过使用@JmxEndpoint
或@WebEndpoint
编写特定于技术的端点。这些端点受限于各自的技术。例如,@WebEndpoint
仅通过HTTP公开,而不通过JMX公开。
您可以通过使用@EndpointWebExtension
和@EndpointJmxExtension
编写特定于技术的扩展。这些注释允许您提供特定于技术的操作,以增强现有端点。
最后,如果您需要访问特定于Web框架的功能,您可以实现Servlet或Spring的@Controller
和@RestController
端点,但这会导致它们无法通过JMX访问,或者在使用不同的Web框架时无法使用。
2.8.1. 接收输入
端点上的操作通过其参数接收输入。在Web上公开时,这些参数的值来自URL的查询参数和JSON请求体。在JMX上公开时,参数被映射到MBean的操作的参数。参数默认是必需的。可以通过使用@javax.annotation.Nullable
或@org.springframework.lang.Nullable
对其进行标注,使其变为可选参数。
您可以将JSON请求体中的每个根属性映射到端点的参数。考虑以下JSON请求体:
{
"name": "test",
"counter": 42
}
您可以使用此来调用一个接受String name
和int counter
参数的写入操作,如以下示例所示:
@WriteOperation
public void updateData(String name, int counter) {
// injects "test" and 42
}
@WriteOperation
fun updateData(name: String?, counter: Int) {
// injects "test" and 42
}
由于端点是技术无关的,方法签名中只能指定简单类型。特别是,声明一个具有name 和counter 属性的CustomData 类型的单个参数是不受支持的。 |
为了让输入映射到操作方法的参数,实现端点的Java代码应该使用-parameters 进行编译,实现端点的Kotlin代码应该使用-java-parameters 进行编译。如果您使用Spring Boot的Gradle插件或者使用Maven和spring-boot-starter-parent ,这将自动发生。 |
2.8.2. 自定义Web端点
@Endpoint
、@WebEndpoint
或@EndpointWebExtension
上的操作会自动通过Jersey、Spring MVC或Spring WebFlux在HTTP上公开。如果Jersey和Spring MVC都可用,则使用Spring MVC。
路径
谓词的路径由端点的ID和Web端点的基本路径确定。默认的基本路径是/actuator
。例如,具有ID为sessions
的端点在谓词中使用/actuator/sessions
作为其路径。
您可以通过使用@Selector
注释操作方法的一个或多个参数来进一步自定义路径。这样的参数将作为路径变量添加到路径谓词中。当调用端点操作时,变量的值将传递到操作方法中。如果要捕获所有剩余的路径元素,可以将@Selector(Match=ALL_REMAINING)
添加到最后一个参数,并将其设置为与String[]
兼容的类型。
HTTP方法
谓词的HTTP方法由操作类型确定,如下表所示:
操作 | HTTP方法 |
---|---|
|
|
|
|
|
|
消费
对于使用请求体的@WriteOperation
(HTTP POST
),谓词的consumes
子句为application/vnd.spring-boot.actuator.v2+json, application/json
。对于所有其他操作,consumes
子句为空。
生成
谓词的produces
子句可以由@DeleteOperation
、@ReadOperation
和@WriteOperation
注释的produces
属性确定。该属性是可选的。如果未使用,produces
子句将自动确定。
如果操作方法返回void
或Void
,则produces
子句为空。如果操作方法返回org.springframework.core.io.Resource
,则produces
子句为application/octet-stream
。对于所有其他操作,produces
子句为application/vnd.spring-boot.actuator.v2+json, application/json
。
Web端点响应状态
端点操作的默认响应状态取决于操作类型(读取、写入或删除)以及操作返回的内容(如果有)。
如果@ReadOperation
返回一个值,则响应状态将为200(OK)。如果不返回值,则响应状态将为404(未找到)。
如果@WriteOperation
或@DeleteOperation
返回一个值,则响应状态将为200(OK)。如果不返回值,则响应状态将为204(无内容)。
如果调用操作时缺少必需参数或参数无法转换为所需类型,则不会调用操作方法,响应状态将为400(错误请求)。
2.9. 健康信息
您可以使用健康信息来检查正在运行的应用程序的状态。监控软件通常会使用它来在生产系统宕机时提醒某人。由health
端点公开的信息取决于management.endpoint.health.show-details
和management.endpoint.health.show-components
属性,这些属性可以配置为以下值之一:
名称 | 描述 |
---|---|
|
从不显示详细信息。 |
|
仅向授权用户显示详细信息。可以使用 |
|
向所有用户显示详细信息。 |
默认值为never
。当用户在端点的一个或多个角色中时,被视为已授权。如果端点没有配置角色(默认情况下),则认为所有经过身份验证的用户都被授权。您可以使用management.endpoint.health.roles
属性配置角色。
如果您已经保护了应用程序并希望使用always ,则您的安全配置必须允许经过身份验证和未经身份验证的用户访问健康端点。 |
健康信息是从HealthContributorRegistry
的内容中收集的(默认情况下,从您的ApplicationContext
中定义的所有HealthContributor
实例)。Spring Boot包括许多自动配置的HealthContributors
,您也可以编写自己的。
HealthContributor
可以是HealthIndicator
或CompositeHealthContributor
。 HealthIndicator
提供实际的健康信息,包括Status
。 CompositeHealthContributor
提供其他HealthContributors
的组合。总体而言,贡献者形成树结构,以表示整个系统的健康状况。
默认情况下,最终系统健康状态由StatusAggregator
推导出来,它根据有序状态列表对每个HealthIndicator
的状态进行排序。排序列表中的第一个状态被用作整体健康状态。如果没有HealthIndicator
返回StatusAggregator
已知的状态,则使用UNKNOWN
状态。
您可以使用HealthContributorRegistry 在运行时注册和注销健康指标。 |
2.9.1. 自动配置的HealthIndicators
在适当的情况下,Spring Boot会自动配置以下表中列出的HealthIndicators
。您还可以通过配置management.health.key.enabled
来启用或禁用选定的指标,其中key
列在以下表中:
键 | 名称 | 描述 |
---|---|---|
|
检查Cassandra数据库是否正常。 |
|
|
检查Couchbase集群是否正常。 |
|
|
检查是否可以连接到 |
|
|
检查磁盘空间是否充足。 |
|
|
检查Elasticsearch集群是否正常。 |
|
|
检查Hazelcast服务器是否正常。 |
|
|
检查InfluxDB服务器是否正常。 |
|
|
检查JMS代理是否正常。 |
|
|
检查LDAP服务器是否正常。 |
|
|
检查邮件服务器是否正常。 |
|
|
检查Mongo数据库是否正常。 |
|
|
检查Neo4j数据库是否正常。 |
|
|
始终响应 |
|
|
检查Rabbit服务器是否正常。 |
|
|
检查Redis服务器是否正常。 |
您可以通过设置management.health.defaults.enabled 属性来禁用所有这些指标。 |
还有其他可用的HealthIndicators
,但默认情况下未启用:
键 | 名称 | 描述 |
---|---|---|
|
公开“Liveness”应用程序可用性状态。 |
|
|
公开“Readiness”应用程序可用性状态。 |
2.9.2. 编写自定义健康指标
要提供自定义健康信息,您可以注册实现 HealthIndicator
接口的 Spring bean。您需要提供 health()
方法的实现并返回一个 Health
响应。 Health
响应应包含一个状态,并可以选择性地包含要显示的附加详细信息。以下代码显示了一个示例 HealthIndicator
实现:
@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() {
// 执行一些特定的健康检查
return ...
}
}
@Component
class MyHealthIndicator : HealthIndicator {
override fun health(): Health {
val errorCode = check()
if (errorCode != 0) {
return Health.down().withDetail("Error Code", errorCode).build()
}
return Health.up().build()
}
private fun check(): Int {
// 执行一些特定的健康检查
return ...
}
}
给定 HealthIndicator 的标识符是没有 HealthIndicator 后缀的 bean 名称。在上面的示例中,健康信息可在名为 my 的条目中找到。 |
健康指标通常通过 HTTP 调用,并需要在任何连接超时之前做出响应。如果健康指标的响应时间超过 10 秒,Spring Boot 将记录警告消息。如果要配置此阈值,可以使用 management.endpoint.health.logging.slow-indicator-threshold 属性。 |
除了 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
management:
endpoint:
health:
status:
order: "fatal,down,out-of-service,unknown,up"
响应中的 HTTP 状态代码反映了整体健康状态。默认情况下,OUT_OF_SERVICE
和 DOWN
映射到 503。包括 UP
在内的任何未映射的健康状态都映射到 200。如果通过 HTTP 访问健康端点,您可能还希望注册自定义状态映射。配置自定义映射会禁用 DOWN
和 OUT_OF_SERVICE
的默认映射。如果要保留默认映射,必须显式配置它们,以及任何自定义映射。例如,以下属性将 FATAL
映射到 503(服务不可用),并保留 DOWN
和 OUT_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
management:
endpoint:
health:
status:
http-mapping:
down: 503
fatal: 503
out-of-service: 503
如果需要更多控制,可以定义自己的 HttpCodeStatusMapper bean。 |
以下表格显示了内置状态的默认状态映射:
状态 | 映射 |
---|---|
|
|
|
|
|
默认情况下没有映射,因此 HTTP 状态为 |
|
默认情况下没有映射,因此 HTTP 状态为 |
2.9.3. 响应式健康指标
对于使用Spring WebFlux等响应式应用程序,ReactiveHealthContributor
提供了一个非阻塞的合同来获取应用程序健康状态。类似于传统的HealthContributor
,健康信息是从ReactiveHealthContributorRegistry
的内容中收集的(默认情况下,从您的ApplicationContext
中定义的所有HealthContributor
和ReactiveHealthContributor
实例)。不检查反应式API的常规HealthContributors
在弹性调度程序上执行。
在响应式应用程序中,您应该使用ReactiveHealthContributorRegistry 在运行时注册和注销健康指标。如果需要注册常规的HealthContributor ,应该使用ReactiveHealthContributor#adapt 进行包装。 |
要从响应式API提供自定义健康信息,您可以注册实现ReactiveHealthIndicator
接口的Spring bean。以下代码显示了一个示例ReactiveHealthIndicator
实现:
@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() {
// 执行一些特定的健康检查
return ...
}
}
@Component
class MyReactiveHealthIndicator : ReactiveHealthIndicator {
override fun health(): Mono<Health> {
return doHealthCheck()!!.onErrorResume { exception: Throwable? ->
Mono.just(Health.Builder().down(exception).build())
}
}
private fun doHealthCheck(): Mono<Health>? {
// 执行一些特定的健康检查
return ...
}
}
要自动处理错误,请考虑扩展自AbstractReactiveHealthIndicator 。 |
2.9.4. 自动配置的响应式健康指标
在适当的情况下,Spring Boot会自动配置以下ReactiveHealthIndicators
:
键 | 名称 | 描述 |
---|---|---|
|
检查Cassandra数据库是否正常。 |
|
|
检查Couchbase集群是否正常。 |
|
|
检查Elasticsearch集群是否正常。 |
|
|
检查Mongo数据库是否正常。 |
|
|
检查Neo4j数据库是否正常。 |
|
|
检查Redis服务器是否正常。 |
如有必要,响应式指标会替换常规指标。此外,任何未明确处理的HealthIndicator 会自动包装。 |
2.9.5. 健康分组
有时将健康指标组织成您可以用于不同目的的组是很有用的。
要创建健康指标组,您可以使用management.endpoint.health.group.<name>
属性,并指定要包含
或排除
的健康指标ID列表。例如,要创建仅包含数据库指标的组,您可以定义如下内容:
management.endpoint.health.group.custom.include=db
management:
endpoint:
health:
group:
custom:
include: "db"
然后,您可以通过访问localhost:8080/actuator/health/custom
来检查结果。
类似地,要创建一个组,从该组中排除数据库指标并包含所有其他指标,您可以定义如下内容:
management.endpoint.health.group.custom.exclude=db
management:
endpoint:
health:
group:
custom:
exclude: "db"
默认情况下,如果健康组包含或排除不存在的健康指标,则启动将失败。要禁用此行为,请将management.endpoint.health.validate-group-membership
设置为false
。
默认情况下,组会继承与系统健康相同的StatusAggregator
和HttpCodeStatusMapper
设置。但是,您也可以在每个组上定义这些设置。如果需要,还可以覆盖show-details
和roles
属性:
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
management:
endpoint:
health:
group:
custom:
show-details: "when-authorized"
roles: "admin"
status:
order: "fatal,up"
http-mapping:
fatal: 500
out-of-service: 500
如果需要为组注册自定义StatusAggregator 或HttpCodeStatusMapper bean,则可以使用@Qualifier("groupname") 。 |
健康组还可以包含/排除CompositeHealthContributor
。您还可以仅包含/排除CompositeHealthContributor
的某个组件。可以通过组件的完全限定名称来执行此操作,如下所示:
management.endpoint.health.group.custom.include="test/primary"
management.endpoint.health.group.custom.exclude="test/primary/b"
在上面的示例中,custom
组将包含名称为primary
的HealthContributor
,该组件是test
的一个组件。在这里,primary
本身是一个组合,名称为b
的HealthContributor
将从custom
组中排除。
健康组可以在主端口或管理端口的附加路径上提供。这在云环境(如Kubernetes)中很有用,因为通常会为执行器端点使用单独的管理端口以提高安全性。使用单独的端口可能导致健康检查不可靠,因为即使健康检查成功,主应用程序可能也无法正常工作。可以如下配置健康组的附加路径:
management.endpoint.health.group.live.additional-path="server:/healthz"
这将使live
健康组在主服务器端口上的/healthz
路径上可用。前缀是必需的,必须是server:
(表示主服务器端口)或management:
(表示管理端口,如果已配置)。路径必须是单个路径段。
2.10. Kubernetes探针
部署在Kubernetes上的应用程序可以使用容器探针提供关于其内部状态的信息。根据您的Kubernetes配置,kubelet调用这些探针并根据结果做出反应。
默认情况下,Spring Boot管理您的应用程序可用状态。如果部署在Kubernetes环境中,执行器会从ApplicationAvailability
接口收集“存活性”和“就绪性”信息,并在专用的健康指标中使用这些信息: LivenessStateHealthIndicator
和 ReadinessStateHealthIndicator
。这些指标显示在全局健康端点("/actuator/health"
)上。它们也通过使用健康组作为单独的HTTP探针公开: "/actuator/health/liveness"
和 "/actuator/health/readiness"
。
然后,您可以使用以下端点信息配置您的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> 应设置为执行器端点可用的端口。它可以是主Web服务器端口,也可以是单独的管理端口,如果已设置"management.server.port" 属性。 |
这些健康组仅在应用程序运行在Kubernetes环境中时自动启用。您可以通过使用management.endpoint.health.probes.enabled
配置属性在任何环境中启用它们。
如果应用程序启动时间超过配置的存活性周期,Kubernetes会提到"startupProbe" 作为可能的解决方案。一般来说,在这里不一定需要"startupProbe" ,因为"readinessProbe" 会在所有启动任务完成之前失败。这意味着您的应用程序在准备就绪之前不会接收流量。但是,如果您的应用程序启动时间很长,请考虑使用"startupProbe" ,以确保Kubernetes在应用程序启动过程中不会终止您的应用程序。请参阅描述应用程序生命周期中探针行为的部分。 |
如果您的执行器端点部署在单独的管理上下文中,则端点不会使用与主应用程序相同的Web基础设施(端口、连接池、框架组件)。在这种情况下,即使主应用程序无法正常工作(例如,无法接受新连接),探针检查也可能成功。因此,将liveness
和readiness
健康组提供在主服务器端口上是一个好主意。这可以通过设置以下属性来实现:
management.endpoint.health.probes.add-additional-paths=true
这将使liveness
组在主服务器端口上的/livez
可用,将readiness
组在主服务器端口上的/readyz
可用。可以使用每个组上的additional-path
属性自定义路径,有关详细信息,请参阅健康组。
2.10.1. 使用Kubernetes探针检查外部状态
执行器将“存活性”和“就绪性”探针配置为健康组。这意味着所有健康组功能对它们都是可用的。例如,您可以配置额外的健康指标:
management.endpoint.health.group.readiness.include=readinessState,customCheck
management:
endpoint:
health:
group:
readiness:
include: "readinessState,customCheck"
默认情况下,Spring Boot不向这些组添加其他健康指标。
“存活性”探针不应依赖于外部系统的健康检查。如果应用程序的存活状态出现问题,Kubernetes会尝试通过重新启动应用程序实例来解决该问题。这意味着如果外部系统(如数据库、Web API或外部缓存)出现故障,Kubernetes可能会重新启动所有应用程序实例并导致级联故障。
至于“就绪性”探针,应用程序开发人员必须谨慎选择检查外部系统。因此,Spring Boot不在就绪性探针中包含任何额外的健康检查。如果应用程序实例的就绪状态不可用,Kubernetes不会将流量路由到该实例。某些外部系统可能不会被应用程序实例共享,在这种情况下,它们可以包含在就绪性探针中。其他外部系统可能对应用程序不是必需的(应用程序可能具有熔断器和回退机制),在这种情况下,它们绝对不应该包含在内。不幸的是,所有应用程序实例共享的外部系统很常见,您必须做出判断:将其包含在就绪性探针中,并期望应用程序在外部服务不可用时被停止,或者将其排除,并处理堆栈更高处的故障,可能通过在调用方使用熔断器来实现。
如果应用程序的所有实例都不可用,具有type=ClusterIP 或NodePort 的Kubernetes服务不会接受任何传入连接。没有HTTP错误响应(例如503等),因为没有连接。具有type=LoadBalancer 的服务可能会或可能不会接受连接,这取决于提供程序。具有显式入口的服务也会以取决于实现的方式做出响应 - 入口服务本身必须决定如何处理下游的“连接被拒绝”。在负载均衡器和入口的情况下,HTTP 503是很可能的。 |
此外,如果应用程序使用Kubernetes自动缩放,它可能会根据其自动缩放器配置对被从负载均衡器中移除的应用程序做出不同的反应。
2.10.2. 应用生命周期和探针状态
与应用生命周期保持一致是Kubernetes探针支持的一个重要方面。AvailabilityState
(这是应用程序的内存中的内部状态)与实际探针之间存在显著差异(它公开该状态)。根据应用程序生命周期的阶段,探针可能不可用。
Spring Boot在启动和关闭过程中发布应用程序事件,探针可以监听这些事件并公开AvailabilityState
信息。
以下表格显示了AvailabilityState
和不同阶段的HTTP连接器状态。
当Spring Boot应用程序启动时:
启动阶段 | 存活状态 | 就绪状态 | HTTP服务器 | 备注 |
---|---|---|---|---|
启动中 |
|
|
未启动 |
Kubernetes检查“存活性”探针,如果时间过长,则重新启动应用程序。 |
已启动 |
|
|
拒绝请求 |
应用程序上下文已刷新。应用程序执行启动任务,但尚未接收流量。 |
就绪 |
|
|
接受请求 |
启动任务已完成。应用程序正在接收流量。 |
当Spring Boot应用程序关闭时:
关闭阶段 | 存活状态 | 就绪状态 | HTTP服务器 | 备注 |
---|---|---|---|---|
运行中 |
|
|
接受请求 |
已请求关闭。 |
优雅关闭 |
|
|
拒绝新请求 |
如果启用,优雅关闭会处理正在处理的请求。 |
关闭完成 |
N/A |
N/A |
服务器已关闭 |
应用程序上下文已关闭,应用程序已关闭。 |
有关Kubernetes部署的更多信息,请参阅Kubernetes容器生命周期部分。 |
2.11. 应用信息
应用信息公开了从您的ApplicationContext
中定义的所有InfoContributor
bean收集的各种信息。Spring Boot包含许多自动配置的InfoContributor
bean,您也可以编写自己的。
2.11.1. 自动配置的InfoContributors
在适当的情况下,Spring会自动配置以下InfoContributor
bean:
ID | 名称 | 描述 | 先决条件 |
---|---|---|---|
|
公开构建信息。 |
一个 |
|
|
公开以 |
无。 |
|
|
公开git信息。 |
一个 |
|
|
公开Java运行时信息。 |
无。 |
|
|
公开操作系统信息。 |
无。 |
个体贡献者是否启用由其management.info.<id>.enabled
属性控制。不同的贡献者对于此属性有不同的默认值,取决于它们的先决条件和所公开信息的性质。
没有指示它们应该启用的先决条件,env
、java
和os
贡献者默认情况下是禁用的。可以通过将其management.info.<id>.enabled
属性设置为true
来启用每个贡献者。
build
和git
信息贡献者默认情况下是启用的。可以通过将其management.info.<id>.enabled
属性设置为false
来禁用每个贡献者。或者,要禁用默认情况下通常启用的每个贡献者,请将management.info.defaults.enabled
属性设置为false
。
2.11.2. 自定义应用信息
当启用env
贡献者时,您可以通过设置info.*
Spring属性来自定义info
端点公开的数据。所有Environment
属性在info
键下都会自动公开。例如,您可以将以下设置添加到您的application.properties
文件中:
info.app.encoding=UTF-8
info.app.java.source=17
info.app.java.target=17
info:
app:
encoding: "UTF-8"
java:
source: "17"
target: "17"
您可以在构建时扩展信息属性,而不是硬编码这些值。 假设您使用Maven,您可以将前面的示例重写如下:
Yaml
|
2.11.3. Git提交信息
info
端点的另一个有用功能是在构建项目时发布有关您的git
源代码库状态的信息的能力。如果有一个GitProperties
bean可用,您可以使用info
端点来公开这些属性。
如果在类路径的根目录下有一个git.properties 文件,则会自动配置一个GitProperties bean。有关更多详细信息,请参阅"如何生成git信息"。 |
默认情况下,如果存在,端点会公开git.branch
、git.commit.id
和git.commit.time
属性。如果您不希望在端点响应中包含这些属性中的任何一个,它们需要从git.properties
文件中排除。如果要显示完整的git信息(即git.properties
的完整内容),请使用management.info.git.mode
属性,如下所示:
management.info.git.mode=full
management:
info:
git:
mode: "full"
要完全禁用info
端点中的git提交信息,请将management.info.git.enabled
属性设置为false
,如下所示:
management.info.git.enabled=false
management:
info:
git:
enabled: false
2.11.4. 构建信息
如果存在一个BuildProperties
bean,则info
端点还可以发布有关构建的信息。如果类路径中存在META-INF/build-info.properties
文件,则会发生这种情况。
Maven和Gradle插件都可以生成该文件。有关更多详细信息,请参见"如何生成构建信息"。 |
2.11.5. Java 信息
info
端点发布有关您的Java运行时环境的信息,请参见JavaInfo
以获取更多详细信息。
2.11.6. 操作系统信息
info
端点发布有关您的操作系统的信息,请参见OsInfo
以获取更多详细信息。
2.11.7. 编写自定义 InfoContributors
要提供自定义应用程序信息,您可以注册实现InfoContributor
接口的Spring bean。
以下示例提供了一个带有单个值的example
条目:
@Component
public class MyInfoContributor implements InfoContributor {
@Override
public void contribute(Info.Builder builder) {
builder.withDetail("example", Collections.singletonMap("key", "value"));
}
}
@Component
class MyInfoContributor : InfoContributor {
override fun contribute(builder: Info.Builder) {
builder.withDetail("example", Collections.singletonMap("key", "value"))
}
}
如果访问info
端点,您应该看到包含以下附加条目的响应:
{
"example": {
"key" : "value"
}
}
3. 监控和管理通过HTTP
如果您正在开发一个Web应用程序,Spring Boot Actuator会自动配置所有已启用的端点以通过HTTP公开。默认约定是使用端点的id
作为URL路径的前缀/actuator
。例如,health
被公开为/actuator/health
。
Actuator在Spring MVC、Spring WebFlux和Jersey中得到原生支持。如果Jersey和Spring MVC都可用,则使用Spring MVC。 |
3.1. 自定义管理端点路径
有时,自定义管理端点的前缀很有用。例如,您的应用程序可能已经使用/actuator
用于其他目的。您可以使用management.endpoints.web.base-path
属性来更改管理端点的前缀,如下例所示:
management.endpoints.web.base-path=/manage
management:
endpoints:
web:
base-path: "/manage"
上述的application.properties
示例将端点从/actuator/{id}
更改为/manage/{id}
(例如,/manage/info
)。
除非已配置管理端口通过不同的HTTP端口公开端点,否则management.endpoints.web.base-path 是相对于server.servlet.context-path (对于Servlet Web应用程序)或spring.webflux.base-path (对于响应式Web应用程序)。如果配置了management.server.port ,management.endpoints.web.base-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
management:
endpoints:
web:
base-path: "/"
path-mapping:
health: "healthcheck"
3.2. 自定义管理服务器端口
通过默认的HTTP端口公开管理端点是云部署的明智选择。但是,如果您的应用程序在自己的数据中心内运行,您可能更喜欢通过不同的HTTP端口公开端点。
您可以设置management.server.port
属性来更改HTTP端口,如下例所示:
management.server.port=8081
management:
server:
port: 8081
在Cloud Foundry上,默认情况下,应用程序仅接收HTTP和TCP路由的8080端口的请求。如果要在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
server:
port: 8443
ssl:
enabled: true
key-store: "classpath:store.jks"
key-password: "secret"
management:
server:
port: 8080
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
server:
port: 8443
ssl:
enabled: true
key-store: "classpath:main.jks"
key-password: "secret"
management:
server:
port: 8080
ssl:
enabled: true
key-store: "classpath:management.jks"
key-password: "secret"
3.4. 自定义管理服务器地址
您可以通过设置management.server.address
属性来自定义管理端点可用的地址。这样做可以很有用,如果您只想监听内部或面向运维的网络,或者只想监听来自localhost
的连接。
只有当端口与主服务器端口不同时,才能监听不同的地址。 |
以下示例的application.properties
不允许远程管理连接:
management.server.port=8081
management.server.address=127.0.0.1
management:
server:
port: 8081
address: "127.0.0.1"
4. 监控和管理JMX
Java管理扩展(JMX)提供了一种标准机制来监控和管理应用程序。默认情况下,此功能未启用。您可以通过将spring.jmx.enabled
配置属性设置为true
来启用它。Spring Boot将最适合的MBeanServer
公开为一个ID为mbeanServer
的bean。任何使用Spring JMX注解(@ManagedResource
、@ManagedAttribute
或@ManagedOperation
)注释的bean都会被公开到其中。
如果您的平台提供了标准的MBeanServer
,Spring Boot将使用该平台,并在必要时默认为VM MBeanServer
。如果所有尝试都失败,将创建一个新的MBeanServer
。
查看JmxAutoConfiguration类以获取更多详细信息。
默认情况下,Spring Boot还将管理端点作为JMX MBeans公开在org.springframework.boot
域下。要完全控制在JMX域中的端点注册,请考虑注册自己的EndpointObjectNameFactory
实现。
4.1. 自定义MBean名称
MBean的名称通常是从端点的id
生成的。例如,health
端点公开为org.springframework.boot:type=Endpoint,name=Health
。
如果您的应用程序包含多个Spring ApplicationContext
,可能会发现名称冲突。为解决此问题,您可以将spring.jmx.unique-names
属性设置为true
,以确保MBean名称始终是唯一的。
您还可以自定义端点公开的JMX域。以下设置显示了在application.properties
中执行此操作的示例:
spring.jmx.unique-names=true
management.endpoints.jmx.domain=com.example.myapp
spring:
jmx:
unique-names: true
management:
endpoints:
jmx:
domain: "com.example.myapp"
5. 可观测性
可观测性是指从外部观察运行中系统的内部状态的能力。它由日志、度量和跟踪三个支柱组成。
对于度量和跟踪,Spring Boot使用 Micrometer Observation。要创建自己的观测(将导致度量和跟踪),您可以注入一个 ObservationRegistry
。
@Component
public class MyCustomObservation {
private final ObservationRegistry observationRegistry;
public MyCustomObservation(ObservationRegistry observationRegistry) {
this.observationRegistry = observationRegistry;
}
public void doSomething() {
Observation.createNotStarted("doSomething", this.observationRegistry)
.lowCardinalityKeyValue("locale", "en-US")
.highCardinalityKeyValue("userId", "42")
.observe(() -> {
// 在这里执行业务逻辑
});
}
}
低基数标签将添加到度量和跟踪中,而高基数标签仅添加到跟踪中。 |
类型为 ObservationPredicate
、GlobalObservationConvention
、ObservationFilter
和 ObservationHandler
的 Bean 将自动注册到 ObservationRegistry
上。您还可以注册任意数量的 ObservationRegistryCustomizer
Bean 来进一步配置注册表。
可观测性支持依赖于 Context Propagation 库,用于在线程和响应式管道之间转发当前观测。默认情况下,ThreadLocal
值不会自动在响应式操作符中恢复。此行为由 spring.reactor.context-propagation
属性控制,可以将其设置为 auto
以启用自动传播。
有关观测的更多详细信息,请参阅 Micrometer Observation 文档。
JDBC 的可观测性可以使用单独的项目进行配置。 Datasource Micrometer 项目 提供了一个 Spring Boot starter,在调用 JDBC 操作时自动创建观测。在 参考文档 中了解更多信息。 |
R2DBC 的可观测性已内置在 Spring Boot 中。要启用它,请将 io.r2dbc:r2dbc-proxy 依赖项添加到您的项目中。 |
5.1. 公共标签
公共标签通常用于对操作环境进行维度下钻,例如主机、实例、区域、堆栈等。公共标签作为低基数标签应用于所有观测中,并且可以进行配置,如下例所示:
management.observations.key-values.region=us-east-1
management.observations.key-values.stack=prod
management:
observations:
key-values:
region: "us-east-1"
stack: "prod"
上述示例将向所有观测添加 region
和 stack
标签,其值分别为 us-east-1
和 prod
。
5.2. 阻止观测
如果您希望阻止某些观测被报告,可以使用 management.observations.enable
属性:
management.observations.enable.denied.prefix=false
management.observations.enable.another.denied.prefix=false
management:
observations:
enable:
denied:
prefix: false
another:
denied:
prefix: false
上述示例将阻止所有名称以 denied.prefix
或 another.denied.prefix
开头的观测。
如果要阻止 Spring Security 报告观测,请将属性 management.observations.enable.spring.security 设置为 false 。 |
如果需要更多对观测阻止的控制,可以注册类型为 ObservationPredicate
的 Bean。只有当所有 ObservationPredicate
Bean 对该观测返回 true
时,才会报告观测。
@Component
class MyObservationPredicate implements ObservationPredicate {
@Override
public boolean test(String name, Context context) {
return !name.contains("denied");
}
}
上述示例将阻止所有名称包含 "denied" 的观测。
5.3. OpenTelemetry 支持
Spring Boot 的执行器模块包含对 OpenTelemetry 的基本支持。
它提供了一个类型为 OpenTelemetry
的 Bean,如果应用程序上下文中存在类型为 SdkTracerProvider
、ContextPropagators
、SdkLoggerProvider
或 SdkMeterProvider
的 Bean,则它们将自动注册。此外,它提供了一个 Resource
Bean。自动配置的 Resource
的属性可以通过 management.opentelemetry.resource-attributes
配置属性进行配置。如果您定义了自己的 Resource
Bean,则不再适用此配置。
Spring Boot 不提供 OpenTelemetry 指标或日志的自动配置。仅当与 Micrometer Tracing 一起使用时,才会自动配置 OpenTelemetry 跟踪。 |
接下来的章节将提供有关日志、度量和跟踪的更多详细信息。
5.4. Micrometer 观测注解支持
要启用对 @Timed
、@Counted
、@MeterTag
和 @NewSpan
等注解的度量和跟踪扫描,您需要将 management.observations.annotations.enabled
属性设置为 true
。此功能由 Micrometer 直接支持,请参阅 Micrometer 和 Micrometer Tracing 参考文档。
7. 指标
Spring Boot Actuator提供了依赖管理和自动配置,支持Micrometer,这是一个应用程序度量门面,支持多种监控系统,包括:
7.1. 入门
Spring Boot自动配置了一个复合MeterRegistry
,并为在类路径上找到的每个受支持的实现添加一个注册表到该复合注册表中。在运行时类路径中具有micrometer-registry-{system}
的依赖足以让Spring Boot配置注册表。
大多数注册表共享通用功能。例如,即使Micrometer注册表实现在类路径上,您也可以禁用特定注册表。以下示例禁用了Datadog:
management.datadog.metrics.export.enabled=false
management:
datadog:
metrics:
export:
enabled: false
您还可以通过注册表特定属性禁用所有注册表,除非另有说明,如以下示例所示:
management.defaults.metrics.export.enabled=false
management:
defaults:
metrics:
export:
enabled: false
Spring Boot还会将任何自动配置的注册表添加到Metrics
类上的全局静态复合注册表中,除非您明确告诉它不要这样做:
management.metrics.use-global-registry=false
management:
metrics:
use-global-registry: false
您可以注册任意数量的MeterRegistryCustomizer
bean来进一步配置注册表,例如在注册表注册任何计量器之前应用通用标记:
@Configuration(proxyBeanMethods = false)
public class MyMeterRegistryConfiguration {
@Bean
public MeterRegistryCustomizer<MeterRegistry> metricsCommonTags() {
return (registry) -> registry.config().commonTags("region", "us-east-1");
}
}
@Configuration(proxyBeanMethods = false)
class MyMeterRegistryConfiguration {
@Bean
fun metricsCommonTags(): MeterRegistryCustomizer<MeterRegistry> {
return MeterRegistryCustomizer { registry ->
registry.config().commonTags("region", "us-east-1")
}
}
}
您可以通过更具体地指定通用类型来对特定注册表实现应用自定义设置:
@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 ...
}
}
@Configuration(proxyBeanMethods = false)
class MyMeterRegistryConfiguration {
@Bean
fun graphiteMetricsNamingConvention(): MeterRegistryCustomizer<GraphiteMeterRegistry> {
return MeterRegistryCustomizer { registry: GraphiteMeterRegistry ->
registry.config().namingConvention(this::name)
}
}
private fun name(name: String, type: Meter.Type, baseUnit: String?): String {
return ...
}
}
Spring Boot还会配置内置的仪表,您可以通过配置或专用注解标记来控制。
7.2. 支持的监控系统
本节简要描述了每个受支持的监控系统。
7.2.1. AppOptics
默认情况下,AppOptics注册表会定期将指标推送到 api.appoptics.com/v1/measurements
。要将指标导出到SaaS AppOptics,必须提供您的API令牌:
management.appoptics.metrics.export.api-token=YOUR_TOKEN
management:
appoptics:
metrics:
export:
api-token: "YOUR_TOKEN"
7.2.2. Atlas
management.atlas.metrics.export.uri=https://atlas.example.com:7101/api/v1/publish
management:
atlas:
metrics:
export:
uri: "https://atlas.example.com:7101/api/v1/publish"
7.2.3. Datadog
management.datadog.metrics.export.api-key=YOUR_KEY
management:
datadog:
metrics:
export:
api-key: "YOUR_KEY"
如果您另外提供应用程序密钥(可选),则还将导出元数据,如计量器描述、类型和基本单位:
management.datadog.metrics.export.api-key=YOUR_API_KEY
management.datadog.metrics.export.application-key=YOUR_APPLICATION_KEY
management:
datadog:
metrics:
export:
api-key: "YOUR_API_KEY"
application-key: "YOUR_APPLICATION_KEY"
默认情况下,指标会发送到 Datadog 美国 站点(api.datadoghq.com
)。如果您的 Datadog 项目托管在其他站点之一,或者需要通过代理发送指标,请相应配置 URI:
management.datadog.metrics.export.uri=https://api.datadoghq.eu
management:
datadog:
metrics:
export:
uri: "https://api.datadoghq.eu"
您还可以更改发送到 Datadog 的指标间隔时间:
management.datadog.metrics.export.step=30s
management:
datadog:
metrics:
export:
step: "30s"
7.2.4. Dynatrace
Dynatrace提供了两种指标摄取API,这两种API都已为v1
命名空间中的配置属性仅在导出到
Timeseries v1 API时应用。在
v2
命名空间中的配置属性仅在导出到
Metrics v2 API时应用。请注意,此集成一次只能导出到
v1
或
v2
API版本之一,
v2
为首选。如果在
v1
命名空间中设置了
device-id
(v1必需但在v2中未使用),则将指标导出到
v1
端点。否则,将假定为
v2
。
v2 API
您可以以两种方式使用v2 API。
自动配置
Dynatrace自动配置适用于由OneAgent或Kubernetes的Dynatrace Operator监控的主机。
本地OneAgent:如果主机上运行着OneAgent,则指标将自动导出到本地OneAgent摄取端点。摄取端点将指标转发到Dynatrace后端。
Dynatrace Kubernetes Operator:在Kubernetes中安装了Dynatrace Operator时,注册表将自动从操作员中获取您的端点URI和API令牌。
这是默认行为,除了依赖于io.micrometer:micrometer-registry-dynatrace
之外,不需要任何特殊设置。
手动配置
如果没有自动配置可用,则需要Metrics v2 API
的端点和API令牌。API令牌必须具有“Ingest metrics”(metrics.ingest
)权限设置。我们建议将令牌的范围限制为此权限。您必须确保端点URI包含路径(例如,/api/v2/metrics/ingest
):
Metrics API v2摄取端点的URL根据您的部署选项而异:
-
SaaS:
https://{your-environment-id}.live.dynatrace.com/api/v2/metrics/ingest
-
托管部署:
https://{your-domain}/e/{your-environment-id}/api/v2/metrics/ingest
下面的示例配置了使用example
环境ID导出指标:
management.dynatrace.metrics.export.uri=https://example.live.dynatrace.com/api/v2/metrics/ingest
management.dynatrace.metrics.export.api-token=YOUR_TOKEN
management:
dynatrace:
metrics:
export:
uri: "https://example.live.dynatrace.com/api/v2/metrics/ingest"
api-token: "YOUR_TOKEN"
使用Dynatrace v2 API时,以下可选功能可用(更多详细信息请参阅Dynatrace文档):
-
指标键前缀:设置添加到所有导出指标键之前的前缀。
-
使用Dynatrace元数据进行丰富:如果OneAgent或Dynatrace操作员正在运行,则使用附加元数据(例如,关于主机、进程或Pod的信息)丰富指标。
-
默认维度:指定添加到所有导出指标的键值对。如果使用Micrometer指定了具有相同键的标签,则它们将覆盖默认维度。
-
使用Dynatrace摘要工具:在某些情况下,Micrometer Dynatrace注册表创建的指标会被拒绝。在Micrometer 1.9.x中,通过引入Dynatrace特定的摘要工具来修复了这个问题。将此切换设置为
false
会强制Micrometer回退到1.9.x之前的默认行为。仅在从Micrometer 1.8.x迁移到1.9.x时遇到问题时才应使用它。 -
导出计量器元数据:从Micrometer 1.12.0开始,Dynatrace导出器还将默认导出计量器元数据,例如单位和描述。使用
export-meter-metadata
切换将此功能关闭。
可以不指定URI和API令牌,如下例所示。在这种情况下,将使用自动配置的端点:
management.dynatrace.metrics.export.v2.metric-key-prefix=your.key.prefix
management.dynatrace.metrics.export.v2.enrich-with-dynatrace-metadata=true
management.dynatrace.metrics.export.v2.default-dimensions.key1=value1
management.dynatrace.metrics.export.v2.default-dimensions.key2=value2
management.dynatrace.metrics.export.v2.use-dynatrace-summary-instruments=true
management.dynatrace.metrics.export.v2.export-meter-metadata=true
management:
dynatrace:
metrics:
export:
# 如果不使用本地OneAgent端点,请在此处指定uri和api-token。
v2:
metric-key-prefix: "your.key.prefix"
enrich-with-dynatrace-metadata: true
default-dimensions:
key1: "value1"
key2: "value2"
use-dynatrace-summary-instruments: true #(默认值:true)
export-meter-metadata: true #(默认值:true)
v1 API(传统)
Dynatrace v1 API指标注册表定期通过使用Timeseries v1 API将指标推送到配置的URI。为了与现有设置向后兼容,当设置了device-id
(v1必需但在v2中未使用)时,将指标导出到Timeseries v1端点。要将指标导出到
management.dynatrace.metrics.export.uri=https://{your-environment-id}.live.dynatrace.com
management.dynatrace.metrics.export.api-token=YOUR_TOKEN
management.dynatrace.metrics.export.v1.device-id=YOUR_DEVICE_ID
management:
dynatrace:
metrics:
export:
uri: "https://{your-environment-id}.live.dynatrace.com"
api-token: "YOUR_TOKEN"
v1:
device-id: "YOUR_DEVICE_ID"
对于v1 API,必须指定不带路径的基本环境URI,因为v1端点路径会自动添加。
与版本无关的设置
除了API端点和令牌,您还可以更改发送指标到Dynatrace的间隔。默认的导出间隔为60s
。以下示例将导出间隔设置为30秒:
management.dynatrace.metrics.export.step=30s
management:
dynatrace:
metrics:
export:
step: "30s"
您可以在Micrometer文档和Dynatrace文档中找到有关如何为Micrometer设置Dynatrace导出器的更多信息。
7.2.5. Elastic
默认情况下,指标会导出到在本地计算机上运行的 Elastic。您可以通过以下属性提供要使用的Elastic服务器的位置:
management.elastic.metrics.export.host=https://elastic.example.com:8086
management:
elastic:
metrics:
export:
host: "https://elastic.example.com:8086"
7.2.6. Ganglia
默认情况下,指标会导出到在本地计算机上运行的 Ganglia。您可以提供 Ganglia服务器 的主机和端口,如下例所示:
management.ganglia.metrics.export.host=ganglia.example.com
management.ganglia.metrics.export.port=9649
management:
ganglia:
metrics:
export:
host: "ganglia.example.com"
port: 9649
7.2.7. Graphite
默认情况下,指标会导出到在本地计算机上运行的 Graphite。您可以提供 Graphite服务器 的主机和端口,如下例所示:
management.graphite.metrics.export.host=graphite.example.com
management.graphite.metrics.export.port=9004
management:
graphite:
metrics:
export:
host: "graphite.example.com"
port: 9004
Micrometer提供了一个默认的 HierarchicalNameMapper
,用于管理维度计量标识如何 映射到平面分层名称。
要控制此行为,定义您自己的
Java
Kotlin
|
7.2.8. Humio
默认情况下,Humio注册表会定期将指标推送到 cloud.humio.com。要将指标导出到SaaS Humio,您必须提供您的API令牌:
management.humio.metrics.export.api-token=YOUR_TOKEN
management:
humio:
metrics:
export:
api-token: "YOUR_TOKEN"
您还应配置一个或多个标签,以标识将指标推送到的数据源:
management.humio.metrics.export.tags.alpha=a
management.humio.metrics.export.tags.bravo=b
management:
humio:
metrics:
export:
tags:
alpha: "a"
bravo: "b"
7.2.9. Influx
默认情况下,指标会导出到在本地计算机上运行的 Influx v1 实例,使用默认配置。要将指标导出到InfluxDB v2,请配置用于写入指标的 org
、bucket
和认证 token
。您可以通过以下方式提供要使用的 Influx服务器 的位置:
management.influx.metrics.export.uri=https://influx.example.com:8086
management:
influx:
metrics:
export:
uri: "https://influx.example.com:8086"
7.2.10. JMX
Micrometer提供了一个层次映射到JMX,主要作为一种便宜且便携的方式在本地查看指标。默认情况下,指标会导出到metrics
JMX域。您可以通过以下方式提供要使用的域:
management.jmx.metrics.export.domain=com.example.app.metrics
management:
jmx:
metrics:
export:
domain: "com.example.app.metrics"
Micrometer提供了一个默认的HierarchicalNameMapper
,用于管理维度计量ID如何映射到平面层次结构名称。
要控制此行为,定义您自己的
Java
Kotlin
|
7.2.11. KairosDB
默认情况下,指标会导出到在您本地机器上运行的KairosDB。您可以通过以下方式提供要使用的KairosDB服务器的位置:
management.kairos.metrics.export.uri=https://kairosdb.example.com:8080/api/v1/datapoints
management:
kairos:
metrics:
export:
uri: "https://kairosdb.example.com:8080/api/v1/datapoints"
7.2.12. New Relic
management.newrelic.metrics.export.api-key=YOUR_KEY
management.newrelic.metrics.export.account-id=YOUR_ACCOUNT_ID
management:
newrelic:
metrics:
export:
api-key: "YOUR_KEY"
account-id: "YOUR_ACCOUNT_ID"
您还可以更改发送指标到New Relic的间隔:
management.newrelic.metrics.export.step=30s
management:
newrelic:
metrics:
export:
step: "30s"
默认情况下,指标通过REST调用发布,但如果类路径上有Java代理API,则也可以使用它:
management.newrelic.metrics.export.client-provider-type=insights-agent
management:
newrelic:
metrics:
export:
client-provider-type: "insights-agent"
最后,您可以通过定义自己的NewRelicClientProvider
bean来完全控制。
7.2.13. OpenTelemetry
默认情况下,指标会导出到在您本地机器上运行的OpenTelemetry。您可以通过以下方式提供要使用的OpenTelemetry指标端点的位置:
management.otlp.metrics.export.url=https://otlp.example.com:4318/v1/metrics
management:
otlp:
metrics:
export:
url: "https://otlp.example.com:4318/v1/metrics"
7.2.14. Prometheus
Prometheus期望对指标进行抓取或轮询单个应用实例。Spring Boot提供了一个位于/actuator/prometheus
的执行器端点,以展示适当格式的Prometheus抓取。
默认情况下,该端点不可用,必须暴露。有关更多详细信息,请参阅暴露端点。 |
以下示例scrape_config
添加到prometheus.yml
中:
scrape_configs:
- job_name: "spring"
metrics_path: "/actuator/prometheus"
static_configs:
- targets: ["HOST:PORT"]
Prometheus示例也受支持。要启用此功能,应存在一个SpanContextSupplier
bean。如果您使用Micrometer跟踪,则会为您自动配置,但如果您愿意,您也可以自行创建。请查看Prometheus文档,因为此功能需要在Prometheus端显式启用,并且仅支持使用OpenMetrics格式。
对于可能不会存在足够长时间以进行抓取的临时或批处理作业,您可以使用Prometheus Pushgateway支持将指标暴露给Prometheus。要启用Prometheus Pushgateway支持,请将以下依赖项添加到您的项目中:
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient_pushgateway</artifactId>
</dependency>
当Prometheus Pushgateway依赖项存在于类路径上并且management.prometheus.metrics.export.pushgateway.enabled
属性设置为true
时,将自动配置一个PrometheusPushGatewayManager
bean。这将管理将指标推送到Prometheus Pushgateway。
您可以通过使用management.prometheus.metrics.export.pushgateway
下的属性来调整PrometheusPushGatewayManager
。对于高级配置,您还可以提供自己的PrometheusPushGatewayManager
bean。
7.2.15. SignalFx
management.signalfx.metrics.export.access-token=YOUR_ACCESS_TOKEN
management:
signalfx:
metrics:
export:
access-token: "YOUR_ACCESS_TOKEN"
您还可以更改发送指标到SignalFx的间隔:
management.signalfx.metrics.export.step=30s
management:
signalfx:
metrics:
export:
step: "30s"
7.2.16. Simple
Micrometer提供了一个简单的内存后端,如果没有配置其他注册表,则会自动用作后备。这使您可以在指标端点中查看收集的指标。
一旦使用任何其他可用后端,内存后端将自动禁用自身。您还可以显式禁用它:
management.simple.metrics.export.enabled=false
management:
simple:
metrics:
export:
enabled: false
7.2.17. Stackdriver
Stackdriver注册表定期将指标推送到Stackdriver。要将指标导出到SaaS Stackdriver,您必须提供您的Google Cloud项目ID:
management.stackdriver.metrics.export.project-id=my-project
management:
stackdriver:
metrics:
export:
project-id: "my-project"
您还可以更改发送指标到Stackdriver的间隔:
management.stackdriver.metrics.export.step=30s
management:
stackdriver:
metrics:
export:
step: "30s"
7.2.18. StatsD
StatsD注册表会急切地通过UDP将指标推送到StatsD代理。默认情况下,指标会导出到在本地计算机上运行的StatsD代理。您可以通过以下方式提供StatsD代理主机、端口和要使用的协议:
management.statsd.metrics.export.host=statsd.example.com
management.statsd.metrics.export.port=9125
management.statsd.metrics.export.protocol=udp
management:
statsd:
metrics:
export:
host: "statsd.example.com"
port: 9125
protocol: "udp"
您还可以更改要使用的StatsD线协议(默认为Datadog):
management.statsd.metrics.export.flavor=etsy
management:
statsd:
metrics:
export:
flavor: "etsy"
7.2.19. Wavefront
management.wavefront.api-token=YOUR_API_TOKEN
management:
wavefront:
api-token: "YOUR_API_TOKEN"
或者,您可以在您的环境中使用Wavefront sidecar或内部代理将指标数据转发到Wavefront API主机:
management.wavefront.uri=proxy://localhost:2878
management:
wavefront:
uri: "proxy://localhost:2878"
如果您将指标发布到Wavefront代理(如Wavefront文档中所述),主机必须采用proxy://HOST:PORT 格式。 |
您还可以更改发送到Wavefront的指标的间隔:
management.wavefront.metrics.export.step=30s
management:
wavefront:
metrics:
export:
step: "30s"
7.3. 支持的指标和计量器
Spring Boot为各种技术提供了自动计量器注册。在大多数情况下,默认值提供了合理的指标,可以发布到任何受支持的监控系统中。
7.3.1. JVM指标
通过使用核心Micrometer类,自动配置启用了JVM指标。JVM指标发布在jvm.
计量器名称下。
提供了以下JVM指标:
-
各种内存和缓冲池详细信息
-
与垃圾回收相关的统计信息
-
线程利用率
-
加载和卸载的类数量
-
JVM版本信息
-
JIT编译时间
7.3.2. 系统指标
通过使用核心Micrometer类,自动配置启用了系统指标。系统指标发布在system.
、process.
和disk.
计量器名称下。
提供了以下系统指标:
-
CPU指标
-
文件描述符指标
-
运行时间指标(应用程序运行时间和绝对启动时间的固定计量)
-
可用磁盘空间
7.3.3. 应用程序启动指标
自动配置暴露了应用程序启动时间指标:
-
application.started.time
:启动应用程序所需的时间。 -
application.ready.time
:应用程序准备好服务请求所需的时间。
指标由应用程序类的完全限定名称标记。
7.3.5. 任务执行和调度指标
自动配置启用了所有可用的ThreadPoolTaskExecutor
和ThreadPoolTaskScheduler
bean的仪表化,只要底层的ThreadPoolExecutor
可用。指标由执行器的名称标记,该名称是从bean名称派生的。
7.3.6. JMS指标
自动配置启用了所有可用的JmsTemplate
bean和@JmsListener
注解方法的仪表化。这将分别产生"jms.message.publish"
和"jms.message.process"
指标。有关生成的观察的更多信息,请参阅Spring Framework参考文档。
7.3.7. Spring MVC指标
自动配置启用了由Spring MVC控制器和功能处理程序处理的所有请求的仪表化。默认情况下,指标生成的名称为http.server.requests
。您可以通过设置management.observations.http.server.requests.name
属性来自定义名称。
有关生成的观察的更多信息,请参阅Spring Framework参考文档。
要添加默认标签,请提供一个扩展自org.springframework.http.server.observation
包中的DefaultServerRequestObservationConvention
的@Bean
。要替换默认标签,请提供一个实现ServerRequestObservationConvention
的@Bean
。
在某些情况下,Web控制器中处理的异常不会记录为请求指标标签。应用程序可以选择记录异常,方法是将处理的异常设置为请求属性。 |
默认情况下,所有请求都会被处理。要自定义过滤器,请提供一个实现FilterRegistrationBean<ServerHttpObservationFilter>
的@Bean
。
7.3.8. Spring WebFlux指标
自动配置启用了由Spring WebFlux控制器和功能处理程序处理的所有请求的仪表化。默认情况下,指标生成的名称为http.server.requests
。您可以通过设置management.observations.http.server.requests.name
属性来自定义名称。
有关生成的观察的更多信息,请参阅Spring Framework参考文档。
要添加默认标签,请提供一个扩展自org.springframework.http.server.reactive.observation
包中的DefaultServerRequestObservationConvention
的@Bean
。要替换默认标签,请提供一个实现ServerRequestObservationConvention
的@Bean
。
在某些情况下,控制器和处理程序中处理的异常不会记录为请求指标标签。应用程序可以选择记录异常,方法是将处理的异常设置为请求属性。 |
7.3.9. Jersey服务器指标
自动配置启用了Jersey JAX-RS实现处理的所有请求的仪表化。默认情况下,指标生成的名称为http.server.requests
。您可以通过设置management.observations.http.server.requests.name
属性来自定义名称。
默认情况下,Jersey服务器指标附带以下信息:
标签 | 描述 |
---|---|
|
处理请求时抛出的任何异常的简单类名。 |
|
请求的方法(例如, |
|
基于响应状态码的请求结果。1xx是 |
|
响应的HTTP状态码(例如, |
|
请求的URI模板在变量替换之前(如果可能)(例如, |
要自定义标签,请提供一个实现JerseyTagsProvider
的@Bean
。
7.3.10. HTTP客户端指标
Spring Boot Actuator管理RestTemplate
、WebClient
和RestClient
的仪表化。为此,您必须注入自动配置的构建器并使用它来创建实例:
-
RestTemplateBuilder
用于RestTemplate
-
WebClient.Builder
用于WebClient
-
RestClient.Builder
用于RestClient
您还可以手动应用负责此仪表化的自定义器,即ObservationRestTemplateCustomizer
、ObservationWebClientCustomizer
和ObservationRestClientCustomizer
。
默认情况下,指标生成的名称为http.client.requests
。您可以通过设置management.observations.http.client.requests.name
属性来自定义名称。
当使用RestTemplate
或RestClient
时,要自定义标签,请提供一个实现org.springframework.http.client.observation
包中的ClientRequestObservationConvention
的@Bean
。当使用WebClient
时要自定义标签,请提供一个实现org.springframework.web.reactive.function.client
包中的ClientRequestObservationConvention
的@Bean
。
7.3.11. Tomcat指标
仅当启用MBeanRegistry
时,自动配置才会启用Tomcat的仪表化。默认情况下,MBeanRegistry
是禁用的,但您可以通过将server.tomcat.mbeanregistry.enabled
设置为true
来启用它。
Tomcat指标发布在tomcat.
计量器名称下。
7.3.12. 缓存指标
自动配置在启动时启用所有可用的Cache
实例的仪表化,指标前缀为cache
。缓存仪表化针对基本一组指标进行了标准化。还提供了其他特定于缓存的指标。
支持以下缓存库:
-
Cache2k
-
Caffeine
-
Hazelcast
-
任何符合JCache(JSR-107)规范的实现
-
Redis
指标按缓存的名称和CacheManager
的名称进行标记,后者是从bean名称派生的。
仅在启动时配置的缓存才绑定到注册表。对于未在缓存配置中定义的缓存(例如在启动阶段之后动态创建或以编程方式创建的缓存),需要显式注册。提供了一个CacheMetricsRegistrar bean来简化该过程。 |
7.3.13. Spring Batch指标
请参阅Spring Batch参考文档。
7.3.15. 数据源指标
自动配置启用所有可用的DataSource
对象的仪表化,指标前缀为jdbc.connections
。数据源仪表化会生成代表池中当前活动、空闲、最大允许和最小允许连接的计量器。
指标还按基于bean名称计算的DataSource
的名称进行标记。
默认情况下,Spring Boot为所有支持的数据源提供元数据。如果您的喜爱数据源不受支持,可以添加额外的DataSourcePoolMetadataProvider bean。请参阅示例DataSourcePoolMetadataProvidersConfiguration 。 |
此外,Hikari特定的指标以hikaricp
前缀公开。每个指标都按池的名称进行标记(您可以使用spring.datasource.name
控制它)。
7.3.16. Hibernate指标
如果类路径上存在org.hibernate.orm:hibernate-micrometer
,则所有可用的启用了统计信息的Hibernate EntityManagerFactory
实例都会被仪表化,指标名为hibernate
。
指标还按EntityManagerFactory
的名称进行标记,该名称是从bean名称派生的。
要启用统计信息,必须将标准JPA属性hibernate.generate_statistics
设置为true
。您可以在自动配置的EntityManagerFactory
上启用它:
spring.jpa.properties[hibernate.generate_statistics]=true
spring:
jpa:
properties:
"[hibernate.generate_statistics]": true
7.3.17. Spring Data Repository指标
自动配置启用所有Spring Data Repository
方法调用的仪表化。默认情况下,指标生成的名称为spring.data.repository.invocations
。您可以通过设置management.metrics.data.repository.metric-name
属性来自定义名称。
支持io.micrometer.core.annotation
包中的@Timed
注解用于Repository
接口和方法。如果不想记录所有Repository
调用的指标,可以将management.metrics.data.repository.autotime.enabled
设置为false
,并仅使用@Timed
注解。
带有longTask = true 的@Timed 注解会为该方法启用长任务计时器。长任务计时器需要单独的指标名称,并且可以与短任务计时器叠加。 |
默认情况下,与存储库调用相关的指标附带以下信息的标签:
标签 | 描述 |
---|---|
|
源 |
|
调用的 |
|
结果状态( |
|
从调用中抛出的任何异常的简单类名。 |
要替换默认标签,请提供一个实现RepositoryTagsProvider
的@Bean
。
7.3.19. Spring Integration指标
每当存在MeterRegistry
bean时,Spring Integration会自动提供Micrometer支持。指标发布在spring.integration.
计量器名称下。
7.3.20. Kafka指标
自动配置为自动配置的消费者工厂和生产者工厂分别注册了一个MicrometerConsumerListener
和MicrometerProducerListener
。它还为StreamsBuilderFactoryBean
注册了一个KafkaStreamsMicrometerListener
。有关更多详细信息,请参阅Spring Kafka文档的Micrometer原生指标部分。
7.3.21. MongoDB指标
本节简要描述了MongoDB的可用指标。
MongoDB命令指标
自动配置为自动配置的MongoClient
注册了一个MongoMetricsCommandListener
。
为底层MongoDB驱动程序发出的每个命令创建了一个名为mongodb.driver.commands
的计时器指标。每个指标默认使用以下信息进行标记:
标记 | 描述 |
---|---|
|
发出的命令的名称。 |
|
发送命令的集群标识符。 |
|
发送命令的服务器地址。 |
|
命令的结果( |
要替换默认的指标标记,请定义一个MongoCommandTagsProvider
bean,如下例所示:
@Configuration(proxyBeanMethods = false)
public class MyCommandTagsProviderConfiguration {
@Bean
public MongoCommandTagsProvider customCommandTagsProvider() {
return new CustomCommandTagsProvider();
}
}
@Configuration(proxyBeanMethods = false)
class MyCommandTagsProviderConfiguration {
@Bean
fun customCommandTagsProvider(): MongoCommandTagsProvider? {
return CustomCommandTagsProvider()
}
}
要禁用自动配置的命令指标,请设置以下属性:
management.metrics.mongo.command.enabled=false
management:
metrics:
mongo:
command:
enabled: false
MongoDB连接池指标
自动配置为自动配置的MongoClient
注册了一个MongoMetricsConnectionPoolListener
。
为连接池创建了以下计量指标:
-
mongodb.driver.pool.size
报告连接池的当前大小,包括空闲和正在使用的成员。 -
mongodb.driver.pool.checkedout
报告当前正在使用的连接数。 -
mongodb.driver.pool.waitqueuesize
报告连接池等待队列的当前大小。
每个指标默认使用以下信息进行标记:
标记 | 描述 |
---|---|
|
连接池对应的集群标识符。 |
|
连接池对应的服务器地址。 |
要替换默认的指标标记,请定义一个MongoConnectionPoolTagsProvider
bean:
@Configuration(proxyBeanMethods = false)
public class MyConnectionPoolTagsProviderConfiguration {
@Bean
public MongoConnectionPoolTagsProvider customConnectionPoolTagsProvider() {
return new CustomConnectionPoolTagsProvider();
}
}
@Configuration(proxyBeanMethods = false)
class MyConnectionPoolTagsProviderConfiguration {
@Bean
fun customConnectionPoolTagsProvider(): MongoConnectionPoolTagsProvider {
return CustomConnectionPoolTagsProvider()
}
}
要禁用自动配置的连接池指标,请设置以下属性:
management.metrics.mongo.connectionpool.enabled=false
management:
metrics:
mongo:
connectionpool:
enabled: false
7.3.22. Jetty指标
自动配置通过使用Micrometer的JettyServerThreadPoolMetrics
为Jetty的ThreadPool
绑定指标。通过使用Micrometer的JettyConnectionMetrics
绑定Jetty的Connector
实例的指标,并且当server.ssl.enabled
设置为true
时,使用Micrometer的JettySslHandshakeMetrics
。
7.3.23. @Timed注解支持
要启用@Timed
注解的扫描,需要将management.observations.annotations.enabled
属性设置为true
。请参阅Micrometer文档。
7.3.24. Redis指标
自动配置为自动配置的LettuceConnectionFactory
注册了一个MicrometerCommandLatencyRecorder
。有关更多详细信息,请参阅Lettuce文档的Micrometer指标部分。
7.4. 注册自定义指标
要注册自定义指标,请将 MeterRegistry
注入到您的组件中:
@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());
}
}
@Component
class MyBean(registry: MeterRegistry) {
private val dictionary: Dictionary
init {
dictionary = Dictionary.load()
registry.gauge("dictionary.size", Tags.empty(), dictionary.words.size)
}
}
如果您的指标依赖于其他 bean,我们建议您使用 MeterBinder
来注册它们:
public class MyMeterBinderConfiguration {
@Bean
public MeterBinder queueSize(Queue queue) {
return (registry) -> Gauge.builder("queueSize", queue::size).register(registry);
}
}
class MyMeterBinderConfiguration {
@Bean
fun queueSize(queue: Queue): MeterBinder {
return MeterBinder { registry ->
Gauge.builder("queueSize", queue::size).register(registry)
}
}
}
使用 MeterBinder
可确保正确设置依赖关系,并在检索指标值时使 bean 可用。如果您发现自己反复在组件或应用程序中为一组指标进行仪器化,MeterBinder
实现也可能很有用。
默认情况下,所有 MeterBinder bean 的指标会自动绑定到 Spring 管理的 MeterRegistry 中。 |
7.5. 自定义单个指标
如果您需要对特定的Meter
实例应用自定义设置,可以使用io.micrometer.core.instrument.config.MeterFilter
接口。
例如,如果您想要将所有以com.example
开头的计量器ID中的mytag.region
标签重命名为mytag.area
,可以执行以下操作:
@Configuration(proxyBeanMethods = false)
public class MyMetricsFilterConfiguration {
@Bean
public MeterFilter renameRegionTagMeterFilter() {
return MeterFilter.renameTag("com.example", "mytag.region", "mytag.area");
}
}
@Configuration(proxyBeanMethods = false)
class MyMetricsFilterConfiguration {
@Bean
fun renameRegionTagMeterFilter(): MeterFilter {
return MeterFilter.renameTag("com.example", "mytag.region", "mytag.area")
}
}
默认情况下,所有MeterFilter bean都会自动绑定到Spring管理的MeterRegistry 。请确保通过使用Spring管理的MeterRegistry 注册您的指标,而不是使用Metrics 上的任何静态方法。这些使用的是全局注册表,而不是Spring管理的注册表。 |
7.5.1. 通用标签
通用标签通常用于在操作环境上进行维度分析,例如主机、实例、区域、堆栈等。通用标签应用于所有计量器,并可以进行配置,如下例所示:
management.metrics.tags.region=us-east-1
management.metrics.tags.stack=prod
management:
metrics:
tags:
region: "us-east-1"
stack: "prod"
上述示例将region
和stack
标签添加到所有计量器中,值分别为us-east-1
和prod
。
如果使用Graphite,通用标签的顺序很重要。由于使用此方法无法保证通用标签的顺序,建议Graphite用户定义自定义的MeterFilter 。 |
7.5.2. 每个计量器属性
除了MeterFilter
bean外,您还可以使用属性在每个计量器基础上应用一组有限的自定义设置。使用Spring Boot的PropertiesMeterFilter
,将应用每个以给定名称开头的计量器ID。以下示例过滤掉任何ID以example.remote
开头的计量器。
management.metrics.enable.example.remote=false
management:
metrics:
enable:
example:
remote: false
以下属性允许每个计量器的自定义设置:
属性 | 描述 |
---|---|
|
是否接受具有特定ID的计量器。未被接受的计量器将从 |
|
是否发布适用于计算可聚合(跨维度)百分位数近似值的直方图。 |
|
通过夹紧预期值的范围来发布更少的直方图桶。 |
|
发布应用程序中计算的百分位数值 |
|
通过在可配置的到期后旋转的环形缓冲区中累积最近的样本,为最近的样本赋予更大的权重,具有可配置的缓冲区长度。 |
|
发布具有由您的服务级别目标定义的桶的累积直方图。 |
有关percentiles-histogram
、percentiles
和slo
背后概念的更多详细信息,请参阅Micrometer文档的“直方图和百分位数”部分。
7.6. 指标端点
Spring Boot提供了一个metrics
端点,您可以用于诊断性地检查应用程序收集的指标。该端点默认情况下不可用,必须暴露。有关更多详细信息,请参见暴露端点。
导航到/actuator/metrics
会显示可用计量器名称的列表。您可以通过提供其名称作为选择器来深入查看有关特定计量器的信息,例如/actuator/metrics/jvm.memory.max
。
此处使用的名称应与代码中使用的名称匹配,而不是在将其规范化为监控系统所需的命名约定后的名称。换句话说,如果由于其蛇形命名约定在Prometheus中 |
您还可以在URL末尾添加任意数量的tag=KEY:VALUE
查询参数,以在计量器上进行维度分析,例如/actuator/metrics/jvm.memory.max?tag=area:nonheap
。
报告的测量值是与匹配计量器名称和已应用的任何标签的所有计量器的统计数据之和。在上述示例中,返回的 |
8. 追踪
Spring Boot Actuator为Micrometer Tracing提供了依赖管理和自动配置,Micrometer Tracing是流行跟踪器库的外观。
要了解有关Micrometer Tracing功能的更多信息,请参阅其参考文档。 |
8.2. 入门指南
我们需要一个示例应用程序,以便开始跟踪。对于我们的目的,覆盖在“getting-started.html”部分中的简单“Hello World!” Web应用程序就足够了。我们将使用OpenTelemetry跟踪器与Zipkin作为跟踪后端。
简而言之,我们的主应用程序代码如下:
@RestController
@SpringBootApplication
public class MyApplication {
private static final Log logger = LogFactory.getLog(MyApplication.class);
@RequestMapping("/")
String home() {
logger.info("home() has been called");
return "Hello World!";
}
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
在home() 方法中添加了一个额外的日志记录语句,稍后会变得重要。 |
现在我们需要添加以下依赖项:
-
org.springframework.boot:spring-boot-starter-actuator
-
io.micrometer:micrometer-tracing-bridge-otel
- 将Micrometer观察API桥接到OpenTelemetry。 -
io.opentelemetry:opentelemetry-exporter-zipkin
- 将跟踪报告给Zipkin。
添加以下应用程序属性:
management.tracing.sampling.probability=1.0
management:
tracing:
sampling:
probability: 1.0
默认情况下,Spring Boot仅对10%的请求进行采样,以防止超载跟踪后端。此属性将其切换为100%,以便将每个请求发送到跟踪后端。
要收集和可视化跟踪,我们需要一个正在运行的跟踪后端。在这里,我们使用Zipkin作为我们的跟踪后端。Zipkin快速入门指南提供了如何在本地启动Zipkin的说明。
启动Zipkin后,您可以启动应用程序。
如果您在Web浏览器中打开localhost:8080
,您应该看到以下输出:
Hello World!
在幕后,已为HTTP请求创建了一个观察,然后将其桥接到OpenTelemetry,后者向Zipkin报告了一个新的跟踪。
现在打开Zipkin UI,网址为localhost:9411
,然后点击“Run Query”按钮以列出所有收集的跟踪。您应该看到一个跟踪。点击“Show”按钮以查看该跟踪的详细信息。
8.3. 记录相关ID
相关ID提供了一种有助于将日志文件中的行与跨度/跟踪相关联的方法。如果您正在使用Micrometer Tracing,Spring Boot将默认在您的日志中包含相关ID。
默认的相关ID是从traceId
和spanId
的MDC值构建的。例如,如果Micrometer Tracing添加了一个MDC traceId
为803B448A0489F84084905D3093480352
和一个MDC spanId
为3425F23BB2432450
,日志输出将包含相关ID[803B448A0489F84084905D3093480352-3425F23BB2432450]
。
如果您希望为相关ID使用不同的格式,可以使用logging.pattern.correlation
属性来定义一个。例如,以下内容将为Logback提供一个与之前Spring Cloud Sleuth使用的格式相同的相关ID:
logging.pattern.correlation=[${spring.application.name:},%X{traceId:-},%X{spanId:-}]
logging.include-application-name=false
logging:
pattern:
correlation: "[${spring.application.name:},%X{traceId:-},%X{spanId:-}] "
include-application-name: false
在上面的示例中,logging.include-application-name 设置为false ,以避免应用程序名称在日志消息中重复(logging.pattern.correlation 已经包含了它)。还值得一提的是,logging.pattern.correlation 包含一个尾随空格,以便默认情况下与紧随其后的记录器名称分隔开来。 |
8.4. 传播跟踪
要自动在网络上传播跟踪,请使用自动配置的RestTemplateBuilder
或WebClient.Builder
来构建客户端。
如果您创建WebClient 或RestTemplate 而不使用自动配置的构建器,则自动跟踪传播将无法工作! |
8.5. 追踪器实现
由于Micrometer Tracer支持多个追踪器实现,因此在Spring Boot中可能存在多种依赖组合。
所有追踪器实现都需要org.springframework.boot:spring-boot-starter-actuator
依赖。
8.5.1. 使用OpenTelemetry与Zipkin
使用OpenTelemetry进行追踪并向Zipkin报告需要以下依赖:
-
io.micrometer:micrometer-tracing-bridge-otel
- 将Micrometer观察API桥接到OpenTelemetry。 -
io.opentelemetry:opentelemetry-exporter-zipkin
- 将追踪报告到Zipkin。
使用management.zipkin.tracing.*
配置属性来配置向Zipkin报告。
8.5.2. 使用OpenTelemetry与Wavefront
使用OpenTelemetry进行追踪并向Wavefront报告需要以下依赖:
-
io.micrometer:micrometer-tracing-bridge-otel
- 将Micrometer观察API桥接到OpenTelemetry。 -
io.micrometer:micrometer-tracing-reporter-wavefront
- 将追踪报告到Wavefront。
使用management.wavefront.*
配置属性来配置向Wavefront报告。
8.5.3. 使用OpenTelemetry与OTLP
使用OpenTelemetry进行追踪并使用OTLP报告需要以下依赖:
-
io.micrometer:micrometer-tracing-bridge-otel
- 将Micrometer观察API桥接到OpenTelemetry。 -
io.opentelemetry:opentelemetry-exporter-otlp
- 将追踪报告到可以接受OTLP的收集器。
使用management.otlp.tracing.*
配置属性来配置使用OTLP报告。
8.5.4. 使用OpenZipkin Brave与Zipkin
使用OpenZipkin Brave进行追踪并向Zipkin报告需要以下依赖:
-
io.micrometer:micrometer-tracing-bridge-brave
- 将Micrometer观察API桥接到Brave。 -
io.zipkin.reporter2:zipkin-reporter-brave
- 将追踪报告到Zipkin。
如果您的项目不使用Spring MVC或Spring WebFlux,则还需要io.zipkin.reporter2:zipkin-sender-urlconnection 依赖。 |
使用management.zipkin.tracing.*
配置属性来配置向Zipkin报告。
8.7. 创建自定义跨度
您可以通过启动观察来创建自己的跨度。为此,请将ObservationRegistry
注入到您的组件中:
@Component
class CustomObservation {
private final ObservationRegistry observationRegistry;
CustomObservation(ObservationRegistry observationRegistry) {
this.observationRegistry = observationRegistry;
}
void someOperation() {
Observation observation = Observation.createNotStarted("some-operation", this.observationRegistry);
observation.lowCardinalityKeyValue("some-tag", "some-value");
observation.observe(() -> {
// 业务逻辑...
});
}
}
这将创建一个名为"some-operation"的观察,带有标签"some-tag=some-value"。
如果要创建一个跨度而不创建度量标准,您需要使用Micrometer的较低级别的Tracer API。 |
8.8. Baggage
您可以使用Tracer
API创建行李:
@Component
class CreatingBaggage {
private final Tracer tracer;
CreatingBaggage(Tracer tracer) {
this.tracer = tracer;
}
void doSomething() {
try (BaggageInScope scope = this.tracer.createBaggageInScope("baggage1", "value1")) {
// 业务逻辑
}
}
}
此示例创建了名为baggage1
的行李,值为value1
。如果您使用W3C传播,行李将自动传播到网络。如果您使用B3传播,行李不会自动传播。要手动将行李传播到网络,请使用management.tracing.baggage.remote-fields
配置属性(这也适用于W3C)。对于上述示例,将此属性设置为baggage1
将导致HTTP头baggage1: value1
。
如果要将行李传播到MDC,请使用management.tracing.baggage.correlation.fields
配置属性。对于上述示例,将此属性设置为baggage1
将导致名为baggage1
的MDC条目。
8.9. 测试
当使用@SpringBootTest
时,报告数据的追踪组件不会自动配置。有关更多详细信息,请参阅测试部分。
9. 审计
一旦Spring Security开始运行,Spring Boot Actuator具有灵活的审计框架,会发布事件(默认情况下为“身份验证成功”,“失败”和“访问被拒绝”异常)。此功能对于报告和基于身份验证失败实施锁定策略非常有用。
您可以通过在应用程序配置中提供AuditEventRepository
类型的bean来启用审计。为方便起见,Spring Boot提供了一个InMemoryAuditEventRepository
。 InMemoryAuditEventRepository
的功能有限,我们建议仅在开发环境中使用它。对于生产环境,请考虑创建自己的替代AuditEventRepository
实现。
10. 记录HTTP交换
您可以通过在应用程序配置中提供HttpExchangeRepository
类型的bean来启用HTTP交换记录。为方便起见,Spring Boot提供了InMemoryHttpExchangeRepository
,默认情况下存储最后100个请求-响应交换。 InMemoryHttpExchangeRepository
与跟踪解决方案相比功能有限,我们建议仅在开发环境中使用它。对于生产环境,建议使用生产就绪的跟踪或可观察性解决方案,如Zipkin或OpenTelemetry。或者,您可以创建自己的HttpExchangeRepository
。
您可以使用httpexchanges
端点获取存储在HttpExchangeRepository
中的请求-响应交换的信息。
11. 进程监控
在spring-boot
模块中,您可以找到两个类来创建通常用于进程监控的文件:
-
ApplicationPidFileWriter
创建一个包含应用程序PID的文件(默认情况下,在应用程序目录中,文件名为application.pid
)。 -
WebServerPortFileWriter
创建一个包含运行Web服务器端口的文件(默认情况下,在应用程序目录中,文件名为application.port
)。
默认情况下,这些写入器未激活,但您可以启用它们:
12. 云原生支持
Spring Boot的执行器模块包含了额外的支持,当您部署到兼容的Cloud Foundry实例时会激活该支持。/cloudfoundryapplication
路径提供了一个替代的安全路由到所有@Endpoint
beans。
扩展支持使得Cloud Foundry管理UI(例如您可以用来查看已部署应用程序的Web应用程序)可以增加Spring Boot执行器信息。例如,应用程序状态页面可以包含完整的健康信息,而不是典型的“运行”或“停止”状态。
/cloudfoundryapplication 路径对普通用户不可直接访问。要使用该端点,您必须在请求中传递有效的UAA令牌。 |
12.1. 禁用扩展的Cloud Foundry执行器支持
如果您想完全禁用/cloudfoundryapplication
端点,您可以将以下设置添加到您的application.properties
文件中:
management.cloudfoundry.enabled=false
management:
cloudfoundry:
enabled: false
12.2. Cloud Foundry自签名证书
默认情况下,对/cloudfoundryapplication
端点的安全验证会对各种Cloud Foundry服务进行SSL调用。如果您的Cloud Foundry UAA或Cloud Controller服务使用自签名证书,您需要设置以下属性:
management.cloudfoundry.skip-ssl-validation=true
management:
cloudfoundry:
skip-ssl-validation: true
12.3. 自定义上下文路径
如果服务器的上下文路径已配置为除/
之外的任何内容,则 Cloud Foundry 端点不会在应用程序的根目录下可用。例如,如果server.servlet.context-path=/app
,则 Cloud Foundry 端点可在/app/cloudfoundryapplication/*
处访问。
如果您希望 Cloud Foundry 端点始终在/cloudfoundryapplication/*
处可用,而不考虑服务器的上下文路径,您需要在应用程序中显式配置。配置因所使用的 Web 服务器而异。对于 Tomcat,您可以添加以下配置:
@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("/*");
};
}
}
@Configuration(proxyBeanMethods = false)
class MyCloudFoundryConfiguration {
@Bean
fun servletWebServerFactory(): TomcatServletWebServerFactory {
return object : TomcatServletWebServerFactory() {
override fun prepareContext(host: Host, initializers: Array<ServletContextInitializer>) {
super.prepareContext(host, initializers)
val child = StandardContext()
child.addLifecycleListener(FixContextListener())
child.path = "/cloudfoundryapplication"
val initializer = getServletContextInitializer(contextPath)
child.addServletContainerInitializer(initializer, emptySet())
child.crossContext = true
host.addChild(child)
}
}
}
private fun getServletContextInitializer(contextPath: String): ServletContainerInitializer {
return ServletContainerInitializer { classes: Set<Class<*>?>?, context: ServletContext ->
val servlet: Servlet = object : GenericServlet() {
@Throws(ServletException::class, IOException::class)
override fun service(req: ServletRequest, res: ServletResponse) {
val servletContext = req.servletContext.getContext(contextPath)
servletContext.getRequestDispatcher("/cloudfoundryapplication").forward(req, res)
}
}
context.addServlet("cloudfoundry", servlet).addMapping("/*")
}
}
}
如果您正在使用基于 Webflux 的应用程序,您可以使用以下配置:
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(WebFluxProperties.class)
public class MyReactiveCloudFoundryConfiguration {
@Bean
public HttpHandler httpHandler(ApplicationContext applicationContext, WebFluxProperties properties) {
HttpHandler httpHandler = WebHttpHandlerBuilder.applicationContext(applicationContext).build();
return new CloudFoundryHttpHandler(properties.getBasePath(), httpHandler);
}
private static final class CloudFoundryHttpHandler implements HttpHandler {
private final HttpHandler delegate;
private final ContextPathCompositeHandler contextPathDelegate;
private CloudFoundryHttpHandler(String basePath, HttpHandler delegate) {
this.delegate = delegate;
this.contextPathDelegate = new ContextPathCompositeHandler(Map.of(basePath, delegate));
}
@Override
public Mono<Void> handle(ServerHttpRequest request, ServerHttpResponse response) {
// 先移除底层上下文路径(例如 Servlet 容器)
String path = request.getPath().pathWithinApplication().value();
if (path.startsWith("/cloudfoundryapplication")) {
return this.delegate.handle(request, response);
}
else {
return this.contextPathDelegate.handle(request, response);
}
}
}
}
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(WebFluxProperties::class)
class MyReactiveCloudFoundryConfiguration {
@Bean
fun httpHandler(applicationContext: ApplicationContext, properties: WebFluxProperties): HttpHandler {
val httpHandler = WebHttpHandlerBuilder.applicationContext(applicationContext).build()
return CloudFoundryHttpHandler(properties.basePath, httpHandler)
}
private class CloudFoundryHttpHandler(basePath: String, private val delegate: HttpHandler) : HttpHandler {
private val contextPathDelegate = ContextPathCompositeHandler(mapOf(basePath to delegate))
override fun handle(request: ServerHttpRequest, response: ServerHttpResponse): Mono<Void> {
// 先移除底层上下文路径(例如 Servlet 容器)
val path = request.path.pathWithinApplication().value()
return if (path.startsWith("/cloudfoundryapplication")) {
delegate.handle(request, response)
} else {
contextPathDelegate.handle(request, response)
}
}
}
}