生产就绪功能
1. 启用生产就绪功能
spring-boot-actuator模块提供了 Spring Boot 的所有 production 就绪功能。
启用这些功能的推荐方法是在 “Starter” 上添加依赖项。spring-boot-starter-actuator
要将 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. 终端节点
Actuator 终端节点允许您监控应用程序并与之交互。
Spring Boot 包含许多内置端点,并允许您添加自己的端点。
例如,终端节点提供基本的应用程序运行状况信息。health
您可以启用或禁用每个单独的终端节点,并通过 HTTP 或 JMX 公开它们(使其可远程访问)。
当终端节点同时启用和公开时,该终端节点被视为可用。
仅当内置终端节点可用时,才会自动配置这些终端节点。
大多数应用程序选择通过 HTTP 进行公开,其中终端节点的 ID 和前缀映射到 URL。
例如,默认情况下,端点映射到 ./actuatorhealth/actuator/health
以下与技术无关的终端节点可用:
| 身份证 | 描述 |
|---|---|
|
公开当前应用程序的审计事件信息。
需要一个 bean。 |
|
显示应用程序中所有 Spring bean 的完整列表。 |
|
公开可用的缓存。 |
|
显示在 configuration 和 auto-configuration 类上评估的条件,以及它们匹配或不匹配的原因。 |
|
显示所有 的整理列表。
需进行消毒。 |
|
公开 Spring 的 .
需进行消毒。 |
|
显示已应用的任何 Flyway 数据库迁移。
需要一个或多个 bean。 |
|
显示应用程序运行状况信息。 |
|
显示 HTTP 交换信息(默认情况下,最后 100 个 HTTP 请求-响应交换)。
需要一个 bean。 |
|
显示任意应用程序信息。 |
|
显示 Spring 集成图。
需要依赖 。 |
|
显示和修改应用程序中记录器的配置。 |
|
显示已应用的任何 Liquibase 数据库迁移。
需要一个或多个 bean。 |
|
显示当前应用程序的 “metrics” 信息。 |
|
显示所有路径的整理列表。 |
|
显示有关 Quartz Scheduler 作业的信息。 需进行消毒。 |
|
显示应用程序中的计划任务。 |
|
允许从 Spring Session 支持的会话存储中检索和删除用户会话。 需要使用 Spring Session 的基于 servlet 的 Web 应用程序。 |
|
允许正常关闭应用程序。 仅在使用 jar 打包时有效。 默认处于禁用状态。 |
|
显示 收集的启动步骤数据。
需要使用 进行配置。 |
|
执行线程转储。 |
如果您的应用程序是 Web 应用程序(Spring MVC、Spring WebFlux 或 Jersey),则可以使用以下附加端点:
| 身份证 | 描述 |
|---|---|
|
返回堆转储文件。
在 HotSpot JVM 上,将返回 -format 文件。
在 OpenJ9 JVM 上,将返回 -format 文件。 |
|
返回日志文件的内容(如果已设置 or 属性)。
支持使用 HTTP 标头检索日志文件的部分内容。 |
|
以 Prometheus 服务器可抓取的格式公开指标。
需要依赖 。 |
2.1. 启用端点
默认情况下,除 之外的所有端点都处于启用状态。
要配置端点的启用,请使用其属性。
以下示例启用终端节点:shutdownmanagement.endpoint.<id>.enabledshutdown
management.endpoint.shutdown.enabled=true
management:
endpoint:
shutdown:
enabled: true
如果您希望终端节点启用选择加入而不是选择退出,请将该属性设置为并使用单个终端节点属性来选择重新加入。
以下示例启用终端节点并禁用所有其他终端节点:management.endpoints.enabled-by-defaultfalseenabledinfo
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 公开运行状况终端节点。 由于 Endpoints 可能包含敏感信息,因此您应该仔细考虑何时公开它们。
要更改公开的终端节点,请使用以下特定于技术的 and 属性:includeexclude
| 财产 | 违约 |
|---|---|
|
|
|
|
|
|
|
|
该属性列出了公开的终端节点的 ID。
该属性列出了不应公开的端点的 ID。
该属性优先于该属性。
您可以使用终端节点 ID 列表配置 和 属性。includeexcludeexcludeincludeincludeexclude
例如,要仅通过 JMX 公开 and 端点,请使用以下属性:healthinfo
management.endpoints.jmx.exposure.include=health,info
management:
endpoints:
jmx:
exposure:
include: "health,info"
*可用于选择所有端点。
例如,要通过 HTTP 公开除 和 endpoints 之外的所有内容,请使用以下属性:envbeans
management.endpoints.web.exposure.include=*
management.endpoints.web.exposure.exclude=env,beans
management:
endpoints:
web:
exposure:
include: "*"
exclude: "env,beans"
*在 YAML 中具有特殊含义,因此如果要包含(或排除)所有终端节点,请务必添加引号。 |
| 如果您的应用程序公开,我们强烈建议您同时保护终端节点。 |
如果要在公开端点时实现自己的策略,则可以注册一个 Bean。EndpointFilter |
2.3. 安全性
出于安全考虑,默认情况下,仅通过 HTTP 公开终端节点。
您可以使用该属性来配置公开的终端节点。/healthmanagement.endpoints.web.exposure.include
在设置之前,请确保公开的 actuator 不包含敏感信息,通过将它们放置在防火墙后面进行保护,或者由 Spring Security 之类的东西进行保护。management.endpoints.web.exposure.include |
如果 Spring Security 在 Classpath 上并且不存在其他 bean,则除 Spring Boot 自动配置外的所有执行器都受到保护。
如果你定义了一个自定义 bean,Spring Boot 自动配置就会退缩,并允许你完全控制 actuator 访问规则。SecurityFilterChain/healthSecurityFilterChain
如果你希望为 HTTP 端点配置自定义安全性(例如,仅允许具有特定角色的用户访问它们),Spring Boot 提供了一些方便的对象,你可以将这些对象与 Spring Security 结合使用。RequestMatcher
典型的 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()
}
}
前面的示例用于将请求与任何终端节点匹配,然后确保所有终端节点都具有该角色。
上还提供了其他几种匹配器方法。
有关详细信息,请参阅 API 文档(HTML 或 PDF)。EndpointRequest.toAnyEndpoint()ENDPOINT_ADMINEndpointRequest
如果您在防火墙后面部署应用程序,您可能希望无需身份验证即可访问所有 actuator 终端节点。
您可以通过更改属性来执行此操作,如下所示: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()
}
}
在上述两个示例中,配置仅适用于 actuator 终端节点。
由于 Spring Boot 的安全配置在存在任何 bean 的情况下完全退缩,因此您需要配置一个额外的 bean,其中包含适用于应用程序其余部分的规则。SecurityFilterChainSecurityFilterChain |
2.3.1. 跨站请求伪造保护
由于 Spring Boot 依赖于 Spring Security 的默认值,因此 CSRF 保护默认处于打开状态。
这意味着在使用默认安全配置时,需要 (shutdown 和 loggers endpoints s)、a 或 a 的 actuator endpoints 会出现 403 (forbidden) 错误。POSTPUTDELETE
| 我们建议仅在您创建的服务由非浏览器客户端使用时才完全禁用 CSRF 保护。 |
您可以在 Spring Security 参考指南中找到有关 CSRF 保护的其他信息。
2.4. 配置端点
终端节点会自动缓存对不采用任何参数的读取操作的响应。
要配置终端节点缓存响应的时间量,请使用其属性。
以下示例将终端节点缓存的生存时间设置为 10 秒:cache.time-to-livebeans
management.endpoint.beans.cache.time-to-live=10s
management:
endpoint:
beans:
cache:
time-to-live: "10s"
前缀唯一标识正在配置的终端节点。management.endpoint.<name> |
2.5. 清理敏感值
和 endpoints 返回的信息可能是敏感的,因此默认情况下,值始终被完全清理(替换为)。/env/configprops/quartz******
只有在以下情况下,才能以未经清理的形式查看值:
-
该属性已设置为非
show-valuesNEVER -
没有自定义 bean 应用
SanitizingFunction
可以将可清理终端节点的属性配置为以下值之一:show-values
-
NEVER- 值始终被完全清理(替换为******) -
ALWAYS- 向所有用户显示值(只要没有 bean 适用)SanitizingFunction -
WHEN_AUTHORIZED- 值仅向授权用户显示(只要没有 Bean 适用)SanitizingFunction
对于 HTTP 端点,如果用户已经过身份验证并且角色由端点的 roles 属性配置,则认为该用户已获得授权。 默认情况下,任何经过身份验证的用户都已获得授权。
对于 JMX 终端节点,所有用户始终获得授权。
以下示例允许具有该角色的所有用户以原始格式查看终端节点中的值。
未经授权的用户或没有该角色的用户将只能看到经过清理的值。admin/envadmin
management.endpoint.env.show-values=WHEN_AUTHORIZED
management.endpoint.env.roles=admin
management:
endpoint:
env:
show-values: WHEN_AUTHORIZED
roles: "admin"
此示例假定尚未定义任何 bean。SanitizingFunction |
2.6. 用于 Actuator Web 端点的超媒体
将添加一个“发现页面”,其中包含指向所有终端节点的链接。
默认情况下,“发现页面”处于打开状态。/actuator
要禁用“发现页面”,请将以下属性添加到您的应用程序属性中:
management.endpoints.web.discovery.enabled=false
management:
endpoints:
web:
discovery:
enabled: false
配置自定义管理上下文路径后,“发现页面” 会自动从管理上下文移动到根目录。
例如,如果管理上下文路径为 ,则可从 获取发现页面。
当 Management context path 设置为 时,将禁用发现页面,以防止与其他映射发生冲突。/actuator/management/management/
2.7. CORS 支持
跨域资源共享 (CORS) 是一种 W3C 规范,可让您以灵活的方式指定授权的跨域请求类型。 如果您使用 Spring MVC 或 Spring WebFlux,则可以配置 Actuator 的 Web 端点以支持此类场景。
CORS 支持默认处于禁用状态,并且仅在您设置了属性后才会启用。
以下配置允许和调用来自域:management.endpoints.web.cors.allowed-originsGETPOSTexample.com
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. 实现自定义端点
如果添加带有 注释 、 则任何带有 、 注释的方法,或者通过 JMX 和 Web 应用程序中的 HTTP 自动公开。
可以使用 Jersey、Spring MVC 或 Spring WebFlux 通过 HTTP 公开端点。
如果 Jersey 和 Spring MVC 都可用,则使用 Spring MVC。@Bean@Endpoint@ReadOperation@WriteOperation@DeleteOperation
以下示例公开返回自定义对象的读取操作:
@ReadOperation
public CustomData getData() {
return new CustomData("test", 5);
}
@ReadOperation
fun getData(): CustomData {
return CustomData("test", 5)
}
您还可以使用 或 编写特定于技术的终端节点。
这些终端节点仅限于各自的技术。
例如,仅通过 HTTP 公开,而不通过 JMX 公开。@JmxEndpoint@WebEndpoint@WebEndpoint
您可以使用 和 编写特定于技术的扩展。
这些注释允许您提供特定于技术的操作来增强现有终端节点。@EndpointWebExtension@EndpointJmxExtension
最后,如果您需要访问特定于 Web 框架的功能,您可以实现 servlet 或 Spring 和端点,但代价是它们无法通过 JMX 使用或使用不同的 Web 框架。@Controller@RestController
2.8.1. 接收输入
终端节点上的操作通过其参数接收输入。
当通过 Web 公开时,这些参数的值取自 URL 的查询参数和 JSON 请求正文。
当通过 JMX 公开时,参数将映射到 MBean 操作的参数。
默认情况下,参数是必需的。
可以通过使用 或 进行注释来使它们成为可选的。@javax.annotation.Nullable@org.springframework.lang.Nullable
您可以将 JSON 请求正文中的每个根属性映射到终端节点的参数。 请考虑以下 JSON 请求正文:
{
"name": "test",
"counter": 42
}
您可以使用它来调用采用 and parameters 的写入操作,如下例所示:String nameint counter
@WriteOperation
public void updateData(String name, int counter) {
// injects "test" and 42
}
@WriteOperation
fun updateData(name: String?, counter: Int) {
// injects "test" and 42
}
由于端点与技术无关,因此只能在方法签名中指定简单类型。
具体而言,不支持使用定义 和 properties 的类型声明单个参数。CustomDatanamecounter |
要使输入映射到操作方法的参数,应使用 编译实现端点的 Java 代码,并使用 编译实现端点的 Kotlin 代码。
如果您使用 Spring Boot 的 Gradle 插件,或者如果您使用 Maven 和 .-parameters-java-parametersspring-boot-starter-parent |
2.8.2. 自定义 Web 端点
对 、 或 的操作使用 Jersey、Spring MVC 或 Spring WebFlux 通过 HTTP 自动公开。
如果 Jersey 和 Spring MVC 都可用,则使用 Spring MVC。@Endpoint@WebEndpoint@EndpointWebExtension
路径
谓词的路径由终端节点的 ID 和 Web 公开的终端节点的基本路径确定。
默认基本路径为 .
例如,ID 为 uses 作为其在谓词中的路径的终端节点。/actuatorsessions/actuator/sessions
您可以通过使用 注释操作方法的一个或多个参数来进一步自定义路径。
此类参数将作为 path 变量添加到 path 谓词中。
调用 endpoint 操作时,变量的值将传递到 operation 方法中。
如果要捕获所有剩余的路径元素,可以添加到最后一个参数,并使其成为与 .@Selector@Selector(Match=ALL_REMAINING)String[]
HTTP 方法
谓词的 HTTP 方法由操作类型决定,如下表所示:
| 操作 | HTTP 方法 |
|---|---|
|
|
|
|
|
|
消耗
对于使用请求正文的 (HTTP) ,谓词的子句为 。
对于所有其他操作,子句为空。@WriteOperationPOSTconsumesapplication/vnd.spring-boot.actuator.v2+json, application/jsonconsumes
生产
谓词的子句可以由 , 和 annotations 的属性确定。
该属性是可选的。
如果未使用,则自动确定子句。producesproduces@DeleteOperation@ReadOperation@WriteOperationproduces
如果操作方法返回 或 ,则该子句为空。
如果操作方法返回 ,则子句为 。
对于所有其他操作,子句为 .voidVoidproducesorg.springframework.core.io.Resourceproducesapplication/octet-streamproducesapplication/vnd.spring-boot.actuator.v2+json, application/json
Web 终端节点响应状态
终端节点操作的默认响应状态取决于操作类型(读取、写入或删除)以及操作返回的内容(如果有)。
如果 a 返回值,则响应状态将为 200 (OK)。
如果未返回值,则响应状态将为 404 (Not Found)。@ReadOperation
如果 a 或 返回值,则响应状态将为 200 (OK)。
如果未返回值,则响应状态将为 204 (No Content)。@WriteOperation@DeleteOperation
如果调用操作时没有必需的参数,或者使用无法转换为必需类型的参数,则不会调用操作方法,并且响应状态将为 400 (Bad Request)。
2.9. 健康信息
您可以使用运行状况信息来检查正在运行的应用程序的状态。
监控软件经常使用它来在生产系统出现故障时提醒某人。
端点公开的信息取决于 和 属性,这些属性可以使用以下值之一进行配置:healthmanagement.endpoint.health.show-detailsmanagement.endpoint.health.show-components
| 名字 | 描述 |
|---|---|
|
详细信息永远不会显示。 |
|
详细信息仅向授权用户显示。
可以使用 配置授权角色。 |
|
详细信息将向所有用户显示。 |
默认值为 .
当用户处于终端节点的一个或多个角色中时,即被视为已获得授权。
如果终端节点没有配置角色(默认),则所有经过身份验证的用户都被视为已获得授权。
您可以使用 property 配置角色。nevermanagement.endpoint.health.roles
如果您已保护应用程序并希望使用 ,则您的安全配置必须允许经过身份验证和未经身份验证的用户访问 health 端点。always |
运行状况信息是从 HealthContributorRegistry 的内容中收集的(默认情况下,在 您的 中定义的所有 HealthContributor 实例)。
Spring Boot 包含许多 auto-configured ,您也可以编写自己的。ApplicationContextHealthContributors
A 可以是 a 或 a 。
A 提供实际的运行状况信息,包括 .
A 提供其他 的复合。
总而言之,贡献者形成一个树结构来表示整个系统的运行状况。HealthContributorHealthIndicatorCompositeHealthContributorHealthIndicatorStatusCompositeHealthContributorHealthContributors
默认情况下,最终的系统运行状况由 派生,它根据状态的有序列表对每个状态进行排序。
排序列表中的第一个状态用作整体运行状况。
如果 no 返回 已知的状态,则使用 状态。StatusAggregatorHealthIndicatorHealthIndicatorStatusAggregatorUNKNOWN
您可以使用 在运行时注册和注销运行状况指示器。HealthContributorRegistry |
2.9.1. 自动配置的 HealthIndicator
在适当的时候, Spring Boot 会自动配置下表中列出的内容。
您还可以通过配置 、 来启用或禁用选定的指示器
下表列出了 :HealthIndicatorsmanagement.health.key.enabledkey
| 钥匙 | 名字 | 描述 |
|---|---|---|
|
检查 Cassandra 数据库是否已启动。 |
|
|
检查 Couchbase 集群是否已启动。 |
|
|
检查是否可以获取 的连接。 |
|
|
检查磁盘空间是否不足。 |
|
|
检查 Elasticsearch 集群是否已启动。 |
|
|
检查 Hazelcast 服务器是否已启动。 |
|
|
检查 InfluxDB 服务器是否已启动。 |
|
|
检查 JMS 代理是否已启动。 |
|
|
检查 LDAP 服务器是否已启动。 |
|
|
检查邮件服务器是否已启动。 |
|
|
检查 Mongo 数据库是否已启动。 |
|
|
检查 Neo4j 数据库是否已启动。 |
|
|
始终以 . |
|
|
检查 Rabbit 服务器是否已启动。 |
|
|
检查 Redis 服务器是否已启动。 |
您可以通过设置属性来禁用它们。management.health.defaults.enabled |
其他功能可用,但默认情况下未启用:HealthIndicators
| 钥匙 | 名字 | 描述 |
|---|---|---|
|
公开 “Liveness” 应用程序可用性状态。 |
|
|
公开 “Readiness” 应用程序可用性状态。 |
2.9.2. 编写自定义 HealthIndicator
要提供自定义运行状况信息,您可以注册实现 HealthIndicator 接口的 Spring bean。
您需要提供该方法的实现并返回响应。
响应应包含状态,并且可以选择包含要显示的其他详细信息。
以下代码显示了一个示例实现:health()HealthHealthHealthIndicator
@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 ...
}
}
@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 {
// perform some specific health check
return ...
}
}
给定的标识符是不带后缀的 bean 的名称(如果存在)。
在前面的示例中,运行状况信息在名为 .HealthIndicatorHealthIndicatormy |
运行状况指示器通常通过 HTTP 调用,并且需要在任何连接超时之前做出响应。
Spring Boot 将记录一条警告消息,用于响应时间超过 10 秒的任何运行状况指示器。
如果要配置此阈值,可以使用 property .management.endpoint.health.logging.slow-indicator-threshold |
除了 Spring Boot 的预定义 Status 类型之外,还可以返回表示新系统状态的自定义。
在这种情况下,您还需要提供 StatusAggregator 接口的自定义实现,或者必须使用 configuration 属性配置默认实现。HealthStatusmanagement.endpoint.health.status.order
例如,假设您的某个实现中使用了代码为 的 new。
要配置严重性顺序,请将以下属性添加到您的应用程序属性中:StatusFATALHealthIndicator
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 状态代码反映了整体运行状况。
默认情况下,映射到 503。
任何未映射的运行状况(包括 )都映射到 200。
如果您通过 HTTP 访问运行状况终端节点,您可能还需要注册自定义状态映射。
配置自定义映射将禁用 和 的默认映射。
如果要保留默认映射,则必须显式配置它们以及任何自定义映射。
例如,以下属性映射到 503(服务不可用)并保留 和 的默认映射:OUT_OF_SERVICEDOWNUPDOWNOUT_OF_SERVICEFATALDOWNOUT_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
如果需要更多控制,可以定义自己的 Bean。HttpCodeStatusMapper |
下表显示了内置状态的默认状态映射:
| 地位 | 映射 |
|---|---|
|
|
|
|
|
默认情况下没有映射,因此 HTTP 状态为 |
|
默认情况下没有映射,因此 HTTP 状态为 |
2.9.3. 反应式健康指标
对于响应式应用程序,例如使用 Spring WebFlux 的应用程序,提供用于获取应用程序运行状况的非阻塞 Contract。
与传统的健康信息类似,是从 ReactiveHealthContributorRegistry 的内容中收集的(默认情况下,在 中定义的所有 HealthContributor 和 ReactiveHealthContributor 实例)。
不检查反应式 API 的常规操作将在弹性调度器上执行。ReactiveHealthContributorHealthContributorApplicationContextHealthContributors
在响应式应用程序中,您应该在运行时使用 register 和 unregister health indicators 。
如果需要注册常规 ,则应将其包装为 .ReactiveHealthContributorRegistryHealthContributorReactiveHealthContributor#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() {
// perform some specific health check
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>? {
// perform some specific health check
return ...
}
}
若要自动处理错误,请考虑从 扩展。AbstractReactiveHealthIndicator |
2.9.4. 自动配置的 ReactiveHealthIndicators
在适当时, Spring Boot 会自动配置以下内容:ReactiveHealthIndicators
| 钥匙 | 名字 | 描述 |
|---|---|---|
|
检查 Cassandra 数据库是否已启动。 |
|
|
检查 Couchbase 集群是否已启动。 |
|
|
检查 Elasticsearch 集群是否已启动。 |
|
|
检查 Mongo 数据库是否已启动。 |
|
|
检查 Neo4j 数据库是否已启动。 |
|
|
检查 Redis 服务器是否已启动。 |
如有必要,反应式指标将替换常规指标。
此外,任何未明确处理的内容都会自动包装。HealthIndicator |
2.9.5. 健康组
有时,将运行状况指示器组织到可用于不同目的的组中非常有用。
要创建运行状况指示器组,可以使用 该属性并将运行状况指示器 ID 列表指定到 或 。
例如,要创建仅包含数据库指示器的组,您可以定义以下内容:management.endpoint.health.group.<name>includeexclude
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-membershipfalse
默认情况下,组继承与系统运行状况相同的 and 设置。
但是,您也可以按组定义这些 ID。
如果需要,您还可以覆盖 and 属性:StatusAggregatorHttpCodeStatusMappershow-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
management:
endpoint:
health:
group:
custom:
show-details: "when-authorized"
roles: "admin"
status:
order: "fatal,up"
http-mapping:
fatal: 500
out-of-service: 500
如果需要注册 custom 或 bean 以用于组,则可以使用。@Qualifier("groupname")StatusAggregatorHttpCodeStatusMapper |
运行状况组还可以包括/排除 .
您还可以仅包含/排除 .
这可以使用组件的完全限定名称来完成,如下所示:CompositeHealthContributorCompositeHealthContributor
management.endpoint.health.group.custom.include="test/primary"
management.endpoint.health.group.custom.exclude="test/primary/b"
在上面的示例中,该组将包含名称为 复合组件 的 。
此处,它本身是一个复合,并且 具有名称的 将从组中排除。customHealthContributorprimarytestprimaryHealthContributorbcustom
运行状况组可以在主端口或管理端口上的其他路径上可用。 这在 Kubernetes 等云环境中很有用,出于安全目的,为 actuator 端点使用单独的 management 端口是很常见的。 拥有单独的端口可能会导致运行状况检查不可靠,因为即使运行状况检查成功,主应用程序也可能无法正常工作。 运行状况组可以配置其他路径,如下所示:
management.endpoint.health.group.live.additional-path="server:/healthz"
这将使运行状况组在主服务器端口上可用。
前缀是必需的,并且必须是 (表示主服务器端口) 或 (表示管理端口,如果已配置)。
路径必须是单个路径段。live/healthzserver:management:
2.10. Kubernetes 探针
部署在 Kubernetes 上的应用程序可以通过 Container Probe 提供有关其内部状态的信息。 根据您的 Kubernetes 配置,kubelet 会调用这些探测并对结果做出反应。
默认情况下, Spring Boot 管理您的应用程序可用性状态。
如果部署在 Kubernetes 环境中,actuator 会从界面收集 “Liveness” 和 “Readiness” 信息,并在专用的运行状况指示器中使用该信息:和 。
这些指示器显示在全局运行状况终端节点 () 上。
它们还通过使用运行状况组作为单独的 HTTP 探测公开:和 .ApplicationAvailabilityLivenessStateHealthIndicatorReadinessStateHealthIndicator"/actuator/health""/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>应设置为 actuator endpoints 可用的端口。
它可以是主 Web 服务器端口,也可以是单独的管理端口(如果已设置该属性)。"management.server.port" |
仅当应用程序在 Kubernetes 环境中运行时,才会自动启用这些运行状况组。
您可以使用 configuration 属性在任何环境中启用它们。management.endpoint.health.probes.enabled
如果应用程序的启动时间超过配置的活跃期,Kubernetes 会提到 这是可能的解决方案。
一般来说,这里不一定需要 the,因为 在完成所有启动任务之前 都会失败。
这意味着您的应用程序在准备就绪之前不会接收流量。
但是,如果您的应用程序需要很长时间才能启动,请考虑使用 a 来确保 Kubernetes 不会在启动过程中终止您的应用程序。
请参阅描述 Probe 在应用程序生命周期中的行为方式的部分。"startupProbe""startupProbe""readinessProbe""startupProbe" |
如果您的 Actuator 端点部署在单独的 Management 上下文中,则端点不会使用与主应用程序相同的 Web 基础架构(端口、连接池、框架组件)。
在这种情况下,即使主应用程序无法正常工作(例如,它无法接受新连接),探测检查也可能成功。
因此,最好在主服务器端口上提供 和 运行状况组。
这可以通过设置以下属性来完成:livenessreadiness
management.endpoint.health.probes.add-additional-paths=true
这将使组在 和 组在主服务器端口上可用。
可以使用每个组上的属性自定义路径,有关详细信息,请参阅运行状况组。liveness/livezreadiness/readyzadditional-path
2.10.1. 使用 Kubernetes 探针检查外部状态
Actuator 将 “liveness” 和 “readiness” 探针配置为 Health Group。 这意味着所有运行状况组功能都可供他们使用。 例如,您可以配置其他运行状况指示器:
management.endpoint.health.group.readiness.include=readinessState,customCheck
management:
endpoint:
health:
group:
readiness:
include: "readinessState,customCheck"
默认情况下, Spring Boot 不会向这些组添加其他运行状况指示器。
“活动性” 探测不应依赖于外部系统的运行状况检查。 如果应用程序的活跃状态被破坏,Kubernetes 会尝试通过重启应用程序实例来解决这个问题。 这意味着,如果外部系统(例如数据库、Web API 或外部缓存)发生故障,Kubernetes 可能会重新启动所有应用程序实例并产生级联故障。
至于 “readiness” 探测,应用程序开发人员必须仔细选择检查外部系统。 因此, Spring Boot 在就绪情况探测中不包括任何其他运行状况检查。 如果应用程序实例的就绪状态为 unready,Kubernetes 不会将流量路由到该实例。 某些外部系统可能不由应用程序实例共享,在这种情况下,它们可能包含在就绪情况探测中。 其他外部系统对于应用程序可能不是必需的(应用程序可能具有断路器和回退),在这种情况下,它们绝对不应包含在内。 不幸的是,所有应用程序实例共享的外部系统是通用的,您必须做出判断:将其包含在就绪情况探测中,并期望当外部服务关闭时应用程序会停止服务,或者将其排除在外,并处理堆栈上层的故障,也许是在调用者中使用断路器。
如果应用程序的所有实例都未就绪,则具有或不接受任何传入连接的 Kubernetes Service。
没有 HTTP 错误响应(503 等),因为没有连接。
服务可能接受也可能不接受连接,具体取决于提供商。
具有显式 Ingress 的服务也以取决于实现的方式进行响应 — Ingress 服务本身必须决定如何处理来自下游的 “connection refused”。
HTTP 503 在负载均衡器和入口的情况下都很可能出现。type=ClusterIPNodePorttype=LoadBalancer |
此外,如果应用程序使用 Kubernetes 自动扩展,则它可能会对从负载均衡器中取出的应用程序做出不同的反应,具体取决于其自动扩展器配置。
2.10.2. 应用程序生命周期和探测状态
Kubernetes 探针支持的一个重要方面是它与应用程序生命周期的一致性。
(这是应用程序中的内存中内部状态)之间存在显著差异
和实际的探针(公开该状态)。
根据应用程序生命周期的阶段,探测可能不可用。AvailabilityState
Spring Boot 在启动和关闭期间发布应用程序事件,
探针可以监听此类事件并公开信息。AvailabilityState
下表显示了 HTTP 连接器在不同阶段的状态。AvailabilityState
当 Spring Boot 应用程序启动时:
| 启动阶段 | LivenessState | 就绪状态 | HTTP 服务器 | 笔记 |
|---|---|---|---|---|
开始 |
|
|
未启动 |
Kubernetes 会检查 “liveness” Probe,如果时间过长,则会重启应用程序。 |
开始 |
|
|
拒绝请求 |
应用程序上下文将刷新。应用程序执行启动任务,但尚未接收流量。 |
准备 |
|
|
接受请求 |
启动任务已完成。应用程序正在接收流量。 |
当 Spring Boot 应用程序关闭时:
| 关闭阶段 | 活动状态 | 就绪状态 | HTTP 服务器 | 笔记 |
|---|---|---|---|---|
运行 |
|
|
接受请求 |
已请求关闭。 |
正常关闭 |
|
|
新请求被拒绝 |
如果启用,正常关闭将处理正在进行的请求。 |
关机完成 |
不适用 |
不适用 |
服务器已关闭 |
应用程序上下文已关闭,应用程序已关闭。 |
| 有关 Kubernetes 部署的更多信息,请参阅 Kubernetes 容器生命周期部分。 |
2.11. 应用程序信息
应用程序信息公开了从 中定义的所有 InfoContributor bean 中收集的各种信息。
Spring Boot 包含许多自动配置的 bean,您可以编写自己的 bean。ApplicationContextInfoContributor
2.11.1. 自动配置的 InfoContributor
在适当的时候, Spring 会自动配置以下 bean:InfoContributor
| 身份证 | 名字 | 描述 | 先决条件 |
|---|---|---|---|
|
公开生成信息。 |
资源。 |
|
|
公开其名称以 开头的任何属性。 |
没有。 |
|
|
公开 git 信息。 |
资源。 |
|
|
公开 Java 运行时信息。 |
没有。 |
|
|
公开 Operating System 信息。 |
没有。 |
是否启用单个贡献者由其属性控制。
不同的参与者对此属性具有不同的默认值,具体取决于其先决条件和他们公开的信息的性质。management.info.<id>.enabled
由于没有先决条件来指示应启用它们,因此默认情况下, , 和 contributors 处于禁用状态。
可以通过将其属性设置为 来启用每个 。envjavaosmanagement.info.<id>.enabledtrue
默认情况下,和 info 参与者处于启用状态。
可以通过将其属性设置为 来禁用 each。
或者,要禁用通常默认启用的每个参与者,请将该属性设置为 。buildgitmanagement.info.<id>.enabledfalsemanagement.info.defaults.enabledfalse
2.11.2. 自定义应用程序信息
启用贡献者后,您可以通过设置 Spring 属性来自定义端点公开的数据。
键下的所有属性都会自动公开。
例如,您可以向文件添加以下设置:envinfoinfo.*Environmentinfoapplication.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"
|
除了对这些值进行硬编码外,您还可以在构建时扩展 info 属性。 假设您使用 Maven,则可以按如下方式重写前面的示例: Yaml
|
2.11.3. Git 提交信息
终端节点的另一个有用功能是,它能够在构建项目时发布有关源代码存储库状态的信息。
如果 Bean 可用,则可以使用端点公开这些属性。infogitGitPropertiesinfo
如果文件在 Classpath 的根目录中可用,则会自动配置 Bean。
有关更多详细信息,请参阅“如何生成 git 信息”。GitPropertiesgit.properties |
默认情况下,终端节点公开 、 和 属性(如果存在)。
如果您不希望终端节点响应中出现这些属性中的任何一个,则需要将它们从文件中排除。
如果要显示完整的 git 信息(即 的完整内容),请使用该属性,如下所示:git.branchgit.commit.idgit.commit.timegit.propertiesgit.propertiesmanagement.info.git.mode
management.info.git.mode=full
management:
info:
git:
mode: "full"
要从端点完全禁用 git 提交信息,请将该属性设置为 ,如下所示:infomanagement.info.git.enabledfalse
management.info.git.enabled=false
management:
info:
git:
enabled: false
2.11.4. 构建信息
如果 Bean 可用,则终端节点还可以发布有关您的构建的信息。
如果 Classpath 中有文件可用,则会发生这种情况。BuildPropertiesinfoMETA-INF/build-info.properties
| Maven 和 Gradle 插件都可以生成该文件。 有关更多详细信息,请参阅“如何生成构建信息”。 |
2.11.5. Java 信息
终端节点发布有关 Java 运行时环境的信息,有关更多详细信息,请参阅 JavaInfo。info
2.11.6. 操作系统信息
终端节点发布有关您的操作系统的信息,有关更多详细信息,请参阅 OsInfo。info
2.11.7. 编写自定义 InfoContributor
要提供自定义应用程序信息,您可以注册实现 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 公开。
默认约定是使用前缀为 的端点作为 URL 路径。
例如,公开为 .id/actuatorhealth/actuator/health
| Spring MVC、Spring WebFlux 和 Jersey 原生支持 Actuator。 如果 Jersey 和 Spring MVC 都可用,则使用 Spring MVC。 |
3.1. 自定义 Management 端点路径
有时,自定义管理终端节点的前缀非常有用。
例如,您的应用程序可能已用于其他目的。
您可以使用该属性更改管理终端节点的前缀,如下例所示:/actuatormanagement.endpoints.web.base-path
management.endpoints.web.base-path=/manage
management:
endpoints:
web:
base-path: "/manage"
前面的示例将 endpoint 从 更改为 (例如 )。application.properties/actuator/{id}/manage/{id}/manage/info
除非已将管理端口配置为使用不同的 HTTP 端口公开端点,否则它是相对于 (对于 servlet Web 应用程序) 或 (对于反应式 Web 应用程序) 的。
如果已配置,则 是相对于 的。management.endpoints.web.base-pathserver.servlet.context-pathspring.webflux.base-pathmanagement.server.portmanagement.endpoints.web.base-pathmanagement.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 端口来公开终端节点。
您可以设置该属性以更改 HTTP 端口,如下例所示:management.server.port
management.server.port=8081
management:
server:
port: 8081
| 在 Cloud Foundry 上,默认情况下,应用程序仅在端口 8080 上接收 HTTP 和 TCP 路由的请求。 如果要在 Cloud Foundry 上使用自定义管理端口,则需要显式设置应用程序的路由以将流量转发到自定义端口。 |
3.3. 配置特定于管理的 SSL
当配置为使用自定义端口时,您还可以使用各种属性使用自己的 SSL 配置 Management Server。
例如,这样做可以让 Management 服务器通过 HTTP 可用,而主应用程序使用 HTTPS,如以下属性设置所示:management.server.ssl.*
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 地址
您可以通过设置属性来自定义管理终端节点可用的地址。
如果您只想侦听内部网络或面向运营的网络,或者只想侦听来自 的连接,则这样做会很有用。management.server.addresslocalhost
| 只有当端口与主服务器端口不同时,您才能侦听其他地址。 |
以下示例不允许远程管理连接: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) 提供了一种用于监视和管理应用程序的标准机制。
默认情况下,此功能未启用。
您可以通过将 configuration 属性设置为 来打开它。
Spring Boot 将最合适的 bean 公开为 ID 为 .
任何使用 Spring JMX 注释(、 或 )注释的 bean 都会暴露给它。spring.jmx.enabledtrueMBeanServermbeanServer@ManagedResource@ManagedAttribute@ManagedOperation
如果您的平台提供 standard ,则 Spring Boot 会使用该 Spring Boot 并在必要时默认为 VM 。
如果所有这些都失败了,则会创建一个新的。MBeanServerMBeanServerMBeanServer
spring.jmx.enabled仅影响 Spring 提供的 Management bean。
启用其他库(例如 Log4j2 或 Quartz)提供的管理 Bean 是独立的。 |
有关更多详细信息,请参见JmxAutoConfiguration类。
默认情况下, Spring Boot 还将 Management 端点公开为域下的 JMX MBean。
要完全控制 JMX 域中的终端节点注册,请考虑注册您自己的实现。org.springframework.bootEndpointObjectNameFactory
4.1. 自定义 MBean 名称
MBean 的名称通常是从终端节点生成的。
例如,终端节点公开为 .idhealthorg.springframework.boot:type=Endpoint,name=Health
如果您的应用程序包含多个 Spring ,您可能会发现名称冲突。
要解决此问题,可以将该属性设置为,以便 MBean 名称始终唯一。ApplicationContextspring.jmx.unique-namestrue
您还可以自定义在其下公开终端节点的 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. 可观测性
可观察性是从外部观察正在运行的系统的内部状态的能力。 它由三个支柱组成:日志记录、指标和跟踪。
对于 metrics 和 traces, 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(() -> {
// Execute business logic here
});
}
}
| 低基数标签将添加到指标和跟踪中,而高基数标签将仅添加到跟踪中。 |
类型的 bean , 和 将自动注册到 .
您还可以注册任意数量的 bean 以进一步配置注册表。ObservationPredicateGlobalObservationConventionObservationFilterObservationHandlerObservationRegistryObservationRegistryCustomizer
可观测性支持依赖于 Context Propagation 库,用于跨线程和反应式管道转发当前观测值。
默认情况下,值不会在 reactive 运算符中自动恢复。
此行为由 property 控制,该属性可以设置为启用自动传播。ThreadLocalspring.reactor.context-propagationauto
有关观测的更多详细信息,请参阅千分尺观测文档。
| JDBC 的可观测性可以使用单独的项目进行配置。 Datasource Micrometer 项目提供了一个 Spring Boot Starters,它可以在调用 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"
前面的示例将 和 标记分别添加到值为 和 的所有观察值。regionstackus-east-1prod
5.2. 阻止 Observation
如果您想阻止报告某些观察结果,您可以使用以下属性: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.prefixanother.denied.prefix
如果要阻止 Spring Security 报告观察结果,请将该属性设置为。management.observations.enable.spring.securityfalse |
如果需要更好地控制 Prevent of observations,则可以注册 type 为 的 bean 。
仅当所有 bean 都返回该观察时,才会报告观察结果。ObservationPredicateObservationPredicatetrue
@Component
class MyObservationPredicate implements ObservationPredicate {
@Override
public boolean test(String name, Context context) {
return !name.contains("denied");
}
}
前面的示例将阻止名称中包含 “denied” 的所有观察。
5.3. OpenTelemetry 支持
| 有几种方法可以在您的应用程序中支持 OpenTelemetry。 您可以使用 OpenTelemetry Java 代理或 OpenTelemetry Spring Boot Starter。 由 OTel 社区支持的;指标和跟踪使用 OTel 库定义的语义约定。 本文档描述了 Spring 团队使用 Micrometer 和 OTLP 导出器正式支持的 OpenTelemetry; 指标和跟踪使用 Spring Projects 文档中描述的语义约定,例如 Spring Framework。 |
Spring Boot 的 actuator 模块包括对 OpenTelemetry 的基本支持。
它提供了一个类型为 , 的 bean,如果存在类型为 , , 的 bean 或在应用程序上下文中,它们会自动注册。
此外,它还提供了一个 bean。
auto-configured 的属性可以通过 configuration 属性进行配置。
如果您定义了自己的 bean,则情况将不再如此。OpenTelemetrySdkTracerProviderContextPropagatorsSdkLoggerProviderSdkMeterProviderResourceResourcemanagement.opentelemetry.resource-attributesResource
| Spring Boot 不提供 OpenTelemetry 指标或日志记录的自动配置。 OpenTelemetry 跟踪仅在与 Micrometer Tracing 一起使用时自动配置。 |
接下来的部分将提供有关日志记录、指标和跟踪的更多详细信息。
5.4. 千分尺观测注释支持
要启用量度扫描和跟踪注释(如 、 和 注释),您需要将属性设置为 。
此功能直接支持 Micrometer,请参考 Micrometer 和 Micrometer Tracing 参考文档。@Timed@Counted@MeterTag@NewSpanmanagement.observations.annotations.enabledtrue
6. 记录器
Spring Boot Actuator 包括在运行时查看和配置应用程序的日志级别的能力。 您可以查看整个列表或单个 Logger 的配置,该配置由显式配置的日志记录级别以及日志记录框架为其提供的有效日志记录级别组成。 这些级别可以是以下级别之一:
-
TRACE -
DEBUG -
INFO -
WARN -
ERROR -
FATAL -
OFF -
null
null表示没有显式配置。
7. 指标
Spring Boot Actuator 为 Micrometer 提供依赖项管理和自动配置,Micrometer 是一个支持众多监控系统的应用程序指标门面,包括:
7.1. 入门
Spring Boot 会自动配置一个组合,并为它在 Classpath 上找到的每个受支持的实现向组合添加一个注册表。
在运行时 Classpath 中具有依赖项就足以让 Spring Boot 配置注册表。MeterRegistrymicrometer-registry-{system}
大多数注册表都具有共同的功能。 例如,即使 Micrometer 注册表实现位于 Classpath 上,您也可以禁用特定的注册表。 以下示例禁用 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
在将任何仪表注册到注册表之前,您可以注册任意数量的 bean 以进一步配置注册表,例如应用通用标记:MeterRegistryCustomizer
@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 还配置了内置插桩,您可以通过配置或专用 Comments 标记来控制这些插桩。
7.2. 支持的监控系统
本节简要介绍每个受支持的监控系统。
7.2.1. AppOptics
默认情况下,AppOptics 注册表会定期将指标推送到 。
要将指标导出到 SaaS AppOptics,必须提供您的 API 令牌:api.appoptics.com/v1/measurements
management.appoptics.metrics.export.api-token=YOUR_TOKEN
management:
appoptics:
metrics:
export:
api-token: "YOUR_TOKEN"
7.2.2. 图集
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 US 站点 ()。
如果您的 Datadog 项目托管在其他站点之一上,或者您需要通过代理发送指标,请相应地配置 URI:api.datadoghq.com
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 都是针对 Micrometer 实现的。
您可以在此处找到有关 Micrometer 指标摄取的 Dynatrace 文档。
命名空间中的配置属性仅在导出到 Timeseries v1 API 时适用。
命名空间中的配置属性仅在导出到 Metrics v2 API 时适用。
请注意,此集成一次只能导出到 API 的 or 版本,这是首选。
如果在命名空间中设置了 (v1 必需,但在 v2 中未使用),则指标将导出到终端节点。
否则,假定为。v1v2v1v2v2device-idv1v1v2
v2 API
您可以通过两种方式使用 v2 API。
自动配置
Dynatrace 自动配置可用于由 OneAgent 或 Dynatrace Operator for Kubernetes 监控的主机。
本地 OneAgent:如果 OneAgent 正在主机上运行,则指标会自动导出到本地 OneAgent 摄取终端节点。 摄取端点将指标转发到 Dynatrace 后端。
Dynatrace Kubernetes 操作员:在安装了 Dynatrace Operator 的 Kubernetes 中运行时,注册表将自动从 Operator 那里获取您的端点 URI 和 API 令牌。
这是默认行为,除了对 的依赖性之外,不需要任何特殊设置。io.micrometer:micrometer-registry-dynatrace
手动配置
如果没有可用的自动配置,则需要 Metrics v2 API 的终端节点和 API 令牌。
API 令牌必须具有“Ingest metrics” () 权限集。
我们建议将令牌的范围限制为此权限。
您必须确保端点 URI 包含路径(例如:metrics.ingest/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
以下示例使用环境 ID 配置指标导出:example
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 文档中找到):
-
Metric key prefix(指标键前缀):设置附加到所有导出的指标键的前缀。
-
使用 Dynatrace 元数据进行扩充:如果 OneAgent 或 Dynatrace 运算符正在运行,请使用其他元数据(例如,关于主机、进程或 pod)来扩充指标。
-
默认维度:指定添加到所有导出指标的键值对。 如果使用 Micrometer 指定了具有相同键的标签,则它们会覆盖默认尺寸。
-
使用 Dynatrace Summary 仪器:在某些情况下,Micrometer Dynatrace 注册表创建的指标被拒绝。 在 Micrometer 1.9.x 中,通过引入 Dynatrace 特定的汇总仪器解决了这个问题。 将此开关设置为强制 Micrometer 回退到 1.9.x 之前的默认值。 它只应在从 Micrometer 1.8.x 迁移到 1.9.x 时遇到问题时使用。
false -
导出仪表元数据:从 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:
# Specify uri and api-token here if not using the local OneAgent endpoint.
v2:
metric-key-prefix: "your.key.prefix"
enrich-with-dynatrace-metadata: true
default-dimensions:
key1: "value1"
key2: "value2"
use-dynatrace-summary-instruments: true # (default: true)
export-meter-metadata: true # (default: true)
v1 API(旧版)
Dynatrace v1 API 指标注册表使用时间序列 v1 API 定期将指标推送到配置的 URI。
为了向后兼容现有设置,设置后(v1 需要,但在 v2 中未使用),指标将导出到时间序列 v1 终端节点。
要将指标导出到 Dynatrace,必须提供您的 API 令牌、设备 ID 和 URI:device-id
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 的间隔。
默认导出间隔为 。
以下示例将导出间隔设置为 30 秒:60s
management.dynatrace.metrics.export.step=30s
management:
dynatrace:
metrics:
export:
step: "30s"
您可以在 Micrometer 文档和 Dynatrace 文档中找到有关如何为 Micrometer 设置 Dynatrace 导出器的更多信息。
7.2.5. 弹性
默认情况下,指标会导出到本地计算机上运行的 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 服务器主机和端口,如下例所示:
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 服务器主机和端口,如下例所示:
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 提供了一个默认值,用于控制如何将维度计 ID 映射到平面分层名称。HierarchicalNameMapper
|
要控制此行为,请定义 your 并提供您自己的 .
除非您定义自己的 bean,否则会提供 auto-configured 和 bean: Java
Kotlin
|
7.2.8. 鹰巢
默认情况下,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 v1 实例。
要将指标导出到 InfluxDB v2,请配置 、 和 身份验证以写入指标。
您可以使用以下方法提供要使用的 Influx 服务器的位置:orgbuckettoken
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 的分层映射,主要作为一种在本地查看指标的廉价且可移植的方式。
默认情况下,指标将导出到 JMX 域。
您可以使用以下方法提供要使用的域:metrics
management.jmx.metrics.export.domain=com.example.app.metrics
management:
jmx:
metrics:
export:
domain: "com.example.app.metrics"
Micrometer 提供了一个默认值,用于控制如何将维度计 ID 映射到平面分层名称。HierarchicalNameMapper
|
要控制此行为,请定义 your 并提供您自己的 .
除非您定义自己的 bean,否则会提供 auto-configured 和 bean: 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 调用发布的,但如果您在 Classpath 上有 Java 代理 API,也可以使用它:
management.newrelic.metrics.export.client-provider-type=insights-agent
management:
newrelic:
metrics:
export:
client-provider-type: "insights-agent"
最后,您可以通过定义自己的 bean 来完全控制。NewRelicClientProvider
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 希望抓取或轮询单个应用程序实例的指标。
Spring Boot 提供了一个 actuator 端点,以呈现具有适当格式的 Prometheus 抓取。/actuator/prometheus
| 默认情况下,终端节点不可用,必须公开。有关更多详细信息,请参阅公开终端节点。 |
以下示例添加到 :scrape_configprometheus.yml
scrape_configs:
- job_name: "spring"
metrics_path: "/actuator/prometheus"
static_configs:
- targets: ["HOST:PORT"]
还支持 Prometheus Exemplars。
要启用此功能,应存在 Bean。
如果您使用 Micrometer Tracing,这将为您自动配置,但您始终可以根据需要创建自己的跟踪。
请查看 Prometheus 文档,因为此功能需要在 Prometheus 端明确启用,并且仅支持使用 OpenMetrics 格式。SpanContextSupplier
对于存在时间不够长而无法抓取的临时或批处理作业,您可以使用 Prometheus Pushgateway 支持向 Prometheus 公开指标。 要启用 Prometheus Pushgateway 支持,请将以下依赖项添加到您的项目中:
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient_pushgateway</artifactId>
</dependency>
当 Classpath 上存在 Prometheus Pushgateway 依赖项并且该属性设置为 时,将自动配置 bean。
这将管理将指标推送到 Prometheus Pushgateway。management.prometheus.metrics.export.pushgateway.enabledtruePrometheusPushGatewayManager
您可以使用 下的属性来优化 。
对于高级配置,您还可以提供自己的 Bean。PrometheusPushGatewayManagermanagement.prometheus.metrics.export.pushgatewayPrometheusPushGatewayManager
7.2.15. 信号变换
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. 简单
Micrometer 附带了一个简单的内存后端,如果未配置其他注册表,则会自动用作后备。 这样,您就可以查看 metrics 终端节点中收集了哪些指标。
一旦您使用任何其他可用的后端,内存中后端就会自行禁用。 您也可以显式禁用它:
management.simple.metrics.export.enabled=false
management:
simple:
metrics:
export:
enabled: false
7.2.17. 堆栈驱动
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. 统计 D
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. 波前
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. 任务执行和调度指标
只要底层可用,自动配置就可以启用所有可用和 bean 的插桩。
度量由执行程序的名称标记,该名称派生自 Bean 名称。ThreadPoolTaskExecutorThreadPoolTaskSchedulerThreadPoolExecutor
7.3.6. JMS 度量
自动配置支持检测所有可用的 bean 和带 Comments 的方法。
这将分别生成 和 metrics。
有关生成的观察结果的更多信息,请参阅 Spring Framework 参考文档。JmsTemplate@JmsListener"jms.message.publish""jms.message.process"
7.3.7. Spring MVC 指标
自动配置可以检测 Spring MVC 控制器和功能处理程序处理的所有请求。
默认情况下,使用名称 .
您可以通过设置属性来自定义名称。http.server.requestsmanagement.observations.http.server.requests.name
要添加到默认标记,请提供从包扩展的 a。
要替换默认标记,请提供实现 .@BeanDefaultServerRequestObservationConventionorg.springframework.http.server.observation@BeanServerRequestObservationConvention
| 在某些情况下,在 Web 控制器中处理的异常不会记录为请求指标标签。 应用程序可以通过将已处理的异常设置为请求属性来选择加入并记录异常。 |
默认情况下,将处理所有请求。
要自定义过滤器,请提供实现 .@BeanFilterRegistrationBean<ServerHttpObservationFilter>
7.3.8. Spring WebFlux 度量
自动配置允许检测 Spring WebFlux 控制器和功能处理程序处理的所有请求。
默认情况下,使用名称 .
您可以通过设置属性来自定义名称。http.server.requestsmanagement.observations.http.server.requests.name
要添加到默认标记,请提供从包扩展的 a。
要替换默认标记,请提供实现 .@BeanDefaultServerRequestObservationConventionorg.springframework.http.server.reactive.observation@BeanServerRequestObservationConvention
| 在某些情况下,控制器和处理程序函数中处理的异常不会记录为请求指标标签。 应用程序可以通过将已处理的异常设置为请求属性来选择加入并记录异常。 |
7.3.9. Jersey 服务器指标
自动配置允许检测 Jersey JAX-RS 实现处理的所有请求。
默认情况下,使用名称 .
您可以通过设置属性来自定义名称。http.server.requestsmanagement.observations.http.server.requests.name
默认情况下,Jersey 服务器指标使用以下信息进行标记:
| 标记 | 描述 |
|---|---|
|
处理请求时引发的任何异常的简单类名。 |
|
请求的方法(例如,或 |
|
请求的结果,基于响应的状态代码。
1xx 是 , 2xx 是 , 3xx 是 , 4xx 是 ,5xx 是 |
|
响应的 HTTP 状态代码(例如 |
|
变量替换之前的请求的 URI 模板(如果可能)(例如 |
要自定义标签,请提供实现 .@BeanJerseyTagsProvider
7.3.10. HTTP 客户端指标
Spring Boot Actuator 管理 、 和 的插桩。
为此,您必须注入自动配置的构建器并使用它来创建实例:RestTemplateWebClientRestClient
-
RestTemplateBuilder为RestTemplate -
WebClient.Builder为WebClient -
RestClient.Builder为RestClient
您还可以手动应用负责此检测的定制器,即 和 。ObservationRestTemplateCustomizerObservationWebClientCustomizerObservationRestClientCustomizer
默认情况下,使用名称 .
您可以通过设置属性来自定义名称。http.client.requestsmanagement.observations.http.client.requests.name
要在使用 或 时自定义标记,请提供从包中实现的标记。
要在使用 时自定义标记,请提供从包中实现的标记。RestTemplateRestClient@BeanClientRequestObservationConventionorg.springframework.http.client.observationWebClient@BeanClientRequestObservationConventionorg.springframework.web.reactive.function.client
7.3.11. Tomcat 度量
自动配置仅在启用 时启用 Tomcat 的检测。
默认情况下,它是禁用的,但您可以通过设置为 来启用它。MBeanRegistryMBeanRegistryserver.tomcat.mbeanregistry.enabledtrue
Tomcat 指标在计量名称下发布。tomcat.
7.3.12. 缓存指标
自动配置允许在启动时检测所有可用实例,其指标前缀为 .
缓存插桩是针对一组基本指标进行标准化的。
此外,还提供了特定于缓存的指标。Cachecache
支持以下缓存库:
-
缓存2k
-
咖啡因
-
Hazelcast
-
任何兼容的 JCache (JSR-107) 实现
-
Redis
度量按缓存的名称和 的名称进行标记,该名称派生自 Bean 名称。CacheManager
只有在启动时配置的缓存才会绑定到注册表。
对于未在缓存配置中定义的缓存,例如在启动阶段之后动态或以编程方式创建的缓存,需要显式注册。
提供了一个 bean 来简化该过程。CacheMetricsRegistrar |
7.3.13. Spring Batch 指标
请参阅 Spring Batch 参考文档。
7.3.14. Spring GraphQL 指标
请参阅 Spring GraphQL 参考文档。
7.3.15. 数据源指标
自动配置支持使用前缀为 的指标检测所有可用对象。
数据源检测会生成表示池中当前活动、空闲、允许的最大连接数和允许的最小连接的仪表。DataSourcejdbc.connections
度量也由基于 Bean 名称计算的名称进行标记。DataSource
默认情况下, Spring Boot 为所有支持的数据源提供元数据。
如果您最喜欢的数据源不受支持,您可以添加其他 Bean。
有关示例,请参阅。DataSourcePoolMetadataProviderDataSourcePoolMetadataProvidersConfiguration |
此外,特定于 Hikari 的指标还带有前缀。
每个量度都由池的名称进行标记(您可以使用 控制它)。hikaricpspring.datasource.name
7.3.16. Hibernate 指标
如果 在 classpath 上,则所有启用了统计信息的可用 Hibernate 实例都使用名为 .org.hibernate.orm:hibernate-micrometerEntityManagerFactoryhibernate
度量还由 的名称进行标记,该名称派生自 Bean 名称。EntityManagerFactory
要启用统计信息,必须将标准 JPA 属性设置为 。
您可以在 auto-configured 上启用它:hibernate.generate_statisticstrueEntityManagerFactory
spring.jpa.properties[hibernate.generate_statistics]=true
spring:
jpa:
properties:
"[hibernate.generate_statistics]": true
7.3.17. Spring Data Repository 指标
自动配置支持所有 Spring Data 方法调用的检测。
默认情况下,使用名称 .
您可以通过设置属性来自定义名称。Repositoryspring.data.repository.invocationsmanagement.metrics.data.repository.metric-name
接口和方法支持包中的 Comments。
如果您不想记录所有调用的指标,则可以改为设置并专门使用注释。@Timedio.micrometer.core.annotationRepositoryRepositorymanagement.metrics.data.repository.autotime.enabledfalse@Timed
带有的注释为该方法启用长任务计时器。
长任务计时器需要单独的指标名称,并且可以与短任务计时器堆叠。@TimedlongTask = true |
默认情况下,存储库调用相关指标使用以下信息进行标记:
| 标记 | 描述 |
|---|---|
|
源 的简单类名 。 |
|
调用的方法的名称。 |
|
结果状态 (、 、 或 )。 |
|
从调用中引发的任何异常的简单类名。 |
要替换默认标记,请提供实现 .@BeanRepositoryTagsProvider
7.3.19. Spring 集成度量
Spring 集成会在 bean 可用时自动提供 Micrometer 支持。
指标在计量名称下发布。MeterRegistryspring.integration.
7.3.20. Kafka 指标
自动配置分别为自动配置的 Consumer Factory 和 producer Factory 注册 a 和 。
它还为 .
有关更多详细信息,请参阅 Spring Kafka 文档的 Micrometer Native Metrics 部分。MicrometerConsumerListenerMicrometerProducerListenerKafkaStreamsMicrometerListenerStreamsBuilderFactoryBean
7.3.21. MongoDB 指标
本节简要介绍了 MongoDB 的可用指标。
MongoDB 命令指标
自动配置将 a 注册到自动配置的 .MongoMetricsCommandListenerMongoClient
为向底层 MongoDB 驱动程序发出的每个命令创建一个名为 的计时器指标。
默认情况下,每个指标都标有以下信息:mongodb.driver.commands
| 标记 | 描述 |
|---|---|
|
发出的命令的名称。 |
|
命令发送到的集群的标识符。 |
|
命令发送到的服务器的地址。 |
|
命令的结果 ( 或 )。 |
要替换默认的 metric 标记,请定义一个 bean,如下例所示:MongoCommandTagsProvider
@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 连接池指标
自动配置将 a 注册到自动配置的 .MongoMetricsConnectionPoolListenerMongoClient
将为连接池创建以下仪表指标:
-
mongodb.driver.pool.size报告连接池的当前大小,包括空闲和正在使用的成员。 -
mongodb.driver.pool.checkedout报告当前正在使用的连接数。 -
mongodb.driver.pool.waitqueuesize报告池中连接的等待队列的当前大小。
默认情况下,每个指标都标有以下信息:
| 标记 | 描述 |
|---|---|
|
连接池对应的集群的标识符。 |
|
连接池对应的服务器的地址。 |
要替换默认的 metric 标记,请定义一个 bean:MongoConnectionPoolTagsProvider
@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 的 .
Jetty 实例的指标使用 Micrometer 的约束,当设置为 Micrometer 时,则使用 Micrometer 的 。ThreadPoolJettyServerThreadPoolMetricsConnectorJettyConnectionMetricsserver.ssl.enabledtrueJettySslHandshakeMetrics
7.3.23. @Timed 注解支持
要启用注释扫描,您需要将属性设置为 。
请参阅 Micrometer 文档。@Timedmanagement.observations.annotations.enabledtrue
7.3.24. Redis 指标
自动配置会为自动配置的 .
有关更多详细信息,请参阅 Lettuce 文档的 Micrometer Metrics 部分。MicrometerCommandLatencyRecorderLettuceConnectionFactory
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)
}
}
如果您的 metrics 依赖于其他 bean,我们建议您使用 a 来注册它们: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)
}
}
}
使用 a 可确保设置正确的依赖关系,并确保在检索度量值时 Bean 可用。
如果您发现跨组件或应用程序重复检测一套指标,则实施也很有用。MeterBinderMeterBinder
默认情况下,来自所有 bean 的度量值都会自动绑定到 Spring-managed 。MeterBinderMeterRegistry |
7.5. 自定义单个指标
如果您需要将自定义项应用于特定实例,可以使用该界面。Meterio.micrometer.core.instrument.config.MeterFilter
例如,如果要将标签重命名为 for all meter IDs starting with ,则可以执行以下操作:mytag.regionmytag.areacom.example
@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")
}
}
默认情况下,所有 bean 都会自动绑定到 Spring-managed 。
确保使用 Spring 管理的 metric 而不是 上的任何 static 方法来注册您的指标。
这些使用非 Spring Management 的全局注册表。MeterFilterMeterRegistryMeterRegistryMetrics |
7.5.1. 常用标签
常用标签通常用于对运行环境进行维度下钻,例如主机、实例、区域、堆栈等。 Commons 标签应用于所有计量,并且可以进行配置,如下例所示:
management.metrics.tags.region=us-east-1
management.metrics.tags.stack=prod
management:
metrics:
tags:
region: "us-east-1"
stack: "prod"
前面的示例将 和 标记分别添加到值为 和 的所有计量器。regionstackus-east-1prod
如果您使用 Graphite,则常用标签的顺序非常重要。
由于使用此方法无法保证常用标记的顺序,因此建议 Graphite 用户改为定义自定义。MeterFilter |
7.5.2. 每米属性
除了 Bean 之外,您还可以使用 properties 按米应用一组有限的自定义。
使用 Spring Boot 的 Per meter 自定义应用于以给定名称开头的任何计量 ID。
以下示例筛选掉 ID 以 .MeterFilterPropertiesMeterFilterexample.remote
management.metrics.enable.example.remote=false
management:
metrics:
enable:
example:
remote: false
以下属性允许按计量进行自定义:
| 财产 | 描述 |
|---|---|
|
是否接受具有特定 ID 的仪表。
不接受的计量将从 中筛选出来。 |
|
是否发布适合计算可聚合(跨维度)百分位数近似值的直方图。 |
|
通过限制预期值的范围来发布更少的直方图存储桶。 |
|
发布在应用程序中计算的百分位值 |
|
通过将最近的样本累积在可配置的到期后轮换的环形缓冲区中,赋予最近的样本更大的权重,其中 可配置的缓冲区长度。 |
|
发布包含由服务级别目标定义的存储桶的累积直方图。 |
有关 、 和 背后的概念的更多详细信息,请参阅 Micrometer 文档的“直方图和百分位数”部分。percentiles-histogrampercentilesslo
7.6. Metrics 端点
Spring Boot 提供了一个终端节点,您可以诊断性地使用它来检查应用程序收集的指标。
默认情况下,终端节点不可用,必须公开。
有关更多详细信息,请参阅公开终端节点。metrics
导航到 将显示可用计量器名称的列表。
您可以通过提供特定计量的名称作为选择器(例如,./actuator/metrics/actuator/metrics/jvm.memory.max
|
您在此处使用的名称应与代码中使用的名称匹配,而不是与针对其寄送到的监控系统进行命名约定规范化后的名称匹配。
换句话说,如果由于 Prometheus 的蛇形大小写命名约定而在 Prometheus 中显示为 Prometheus,则在检查终端节点中的仪表时,您仍应用作选择器。 |
您还可以在 URL 末尾添加任意数量的查询参数,以便对计量器进行维度向下钻取,例如 .tag=KEY:VALUE/actuator/metrics/jvm.memory.max?tag=area:nonheap
|
报告的测量值是与仪表名称和已应用的任何标签匹配的所有仪表的统计数据的总和。
在前面的示例中,返回的统计数据是堆的 “Code Cache”、“Compressed Class Space” 和 “Metaspace” 区域的最大内存占用量之和。
如果您只想查看 “Metaspace” 的最大大小,您可以添加一个额外的 — 即 . |
8. 跟踪
Spring Boot Actuator 为 Micrometer Tracing 提供依赖项管理和自动配置,Micrometer Tracing是流行的 Tracer 库的门面。
| 要了解有关 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);
}
}
该方法中添加了一个 logger 语句,这在后面会很重要。home() |
现在我们必须添加以下依赖项:
-
org.springframework.boot:spring-boot-starter-actuator -
io.micrometer:micrometer-tracing-bridge-otel- 将 Micrometer Observation 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 并按“Run Query”按钮列出所有收集的跟踪。
您应该会看到一条跟踪。
按 “Show” 按钮查看该跟踪的详细信息。localhost:9411
8.3. 记录关联 ID
相关 ID 提供了一种将日志文件中的行链接到 span/traces 的有用方法。 如果您使用的是 Micrometer Tracing,则默认情况下, Spring Boot 将在日志中包含相关 ID。
默认相关 ID 是根据 MDC 值构建的。
例如,如果 Micrometer Tracing 添加了 MDC 和 MDC 的日志输出将包含相关 ID 。traceIdspanIdtraceId803B448A0489F84084905D3093480352spanId3425F23BB2432450[803B448A0489F84084905D3093480352-3425F23BB2432450]
如果您希望对相关 ID 使用不同的格式,则可以使用该属性来定义一个格式。
例如,以下内容将以 Spring Cloud Sleuth 以前使用的格式为 Logback 提供相关 ID:logging.pattern.correlation
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
在上面的示例中, 设置为 以避免应用程序名称在日志消息中重复( 已包含它)。
还值得一提的是,它包含一个尾随空格,因此默认情况下它与紧随其后的 Logger 名称分开。logging.include-application-namefalselogging.pattern.correlationlogging.pattern.correlation |
8.4. 传播跟踪
要通过网络自动传播跟踪,请使用自动配置的 RestTemplateBuilder、RestClient.Builder 或 WebClient.Builder 来构建客户端。
如果您在不使用自动配置的生成器的情况下创建 、 或 ,则自动跟踪传播将不起作用!RestTemplateRestClientWebClient |
8.5. Tracer 实现
由于 Micrometer Tracer 支持多个 tracer 实现,因此 Spring Boot 可以有多种依赖项组合。
所有 tracer 实现都需要 dependency。org.springframework.boot:spring-boot-starter-actuator
8.5.1. 使用 Zipkin 的 OpenTelemetry
使用 OpenTelemetry 进行跟踪并向 Zipkin 报告需要以下依赖项:
-
io.micrometer:micrometer-tracing-bridge-otel- 将 Micrometer Observation API 桥接到 OpenTelemetry。 -
io.opentelemetry:opentelemetry-exporter-zipkin- 向 Zipkin 报告跟踪。
使用配置属性配置向 Zipkin 报告。management.zipkin.tracing.*
8.5.2. 使用 Wavefront 的 OpenTelemetry
使用 OpenTelemetry 进行跟踪并向 Wavefront 报告需要以下依赖项:
-
io.micrometer:micrometer-tracing-bridge-otel- 将 Micrometer Observation API 桥接到 OpenTelemetry。 -
io.micrometer:micrometer-tracing-reporter-wavefront- 向 Wavefront 报告跟踪。
使用配置属性配置向 Wavefront 报告。management.wavefront.*
8.5.3. 使用 OTLP 的 OpenTelemetry
使用 OpenTelemetry 进行跟踪和使用 OTLP 进行报告需要以下依赖项:
-
io.micrometer:micrometer-tracing-bridge-otel- 将 Micrometer Observation API 桥接到 OpenTelemetry。 -
io.opentelemetry:opentelemetry-exporter-otlp- 将跟踪报告给可以接受 OTLP 的收集器。
使用配置属性来配置使用 OTLP 的报告。management.otlp.tracing.*
8.5.4. 使用 Zipkin 的 OpenZipkin Brave
使用 OpenZipkin Brave 进行跟踪并向 Zipkin 报告需要以下依赖项:
-
io.micrometer:micrometer-tracing-bridge-brave- 将 Micrometer Observation API 桥接到 Brave。 -
io.zipkin.reporter2:zipkin-reporter-brave- 向 Zipkin 报告跟踪。
如果您的项目不使用 Spring MVC 或 Spring WebFlux,则还需要依赖项。io.zipkin.reporter2:zipkin-sender-urlconnection |
使用配置属性配置向 Zipkin 报告。management.zipkin.tracing.*
8.7. 创建自定义 Span
您可以通过开始观察来创建自己的范围。
为此,请注入到你的组件中: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(() -> {
// Business logic ...
});
}
}
这将创建一个名为 “some-operation” 的观察,其标签为 “some-tag=some-value”。
如果要在不创建指标的情况下创建 span,则需要使用 Micrometer 的较低级别 Tracer API。 |
8.8. 行李
您可以使用 API 创建行李:Tracer
@Component
class CreatingBaggage {
private final Tracer tracer;
CreatingBaggage(Tracer tracer) {
this.tracer = tracer;
}
void doSomething() {
try (BaggageInScope scope = this.tracer.createBaggageInScope("baggage1", "value1")) {
// Business logic
}
}
}
此示例创建以值 .
如果你使用的是 W3C 传播,那么 Baggage 会自动通过网络传播。
如果您使用的是 B3 传播,则不会自动传播 baggage。
要在网络上手动传播 Baggage,请使用 configuration 属性(这也适用于 W3C)。
在上面的示例中,将此属性设置为会导致 HTTP 标头 。baggage1value1management.tracing.baggage.remote-fieldsbaggage1baggage1: value1
如果要将 baggage 传播到 MDC,请使用 configuration 属性。
在上面的示例中,将此属性设置为 将导致名为 的 MDC 条目。management.tracing.baggage.correlation.fieldsbaggage1baggage1
8.9. 测试
使用 时,不会自动配置报告数据的跟踪组件。
有关更多详细信息,请参阅 testing 部分。@SpringBootTest
9. 审计
一旦 Spring Security 开始发挥作用, Spring Boot Actuator 就会有一个灵活的审计框架来发布事件(默认情况下,“身份验证成功”、“失败”和“访问被拒绝”异常)。 此功能对于报告和实施基于身份验证失败的锁定策略非常有用。
您可以通过在应用程序的配置中提供 类型的 bean 来启用审计。
为方便起见,Spring Boot 提供了一个 . 功能有限,我们建议仅将其用于开发环境。
对于生产环境,请考虑创建自己的替代实现。AuditEventRepositoryInMemoryAuditEventRepositoryInMemoryAuditEventRepositoryAuditEventRepository
10. 记录 HTTP 交换
您可以通过在应用程序的配置中提供 type 的 bean 来启用 HTTP 交换的记录。
为方便起见, Spring Boot 提供了 ,默认情况下,它存储了最后 100 个请求-响应交换。 与跟踪解决方案相比受到限制,我们建议仅将其用于开发环境。
对于生产环境,我们建议使用生产就绪的跟踪或可观测性解决方案,例如 Zipkin 或 OpenTelemetry。
或者,您也可以创建自己的 .HttpExchangeRepositoryInMemoryHttpExchangeRepositoryInMemoryHttpExchangeRepositoryHttpExchangeRepository
您可以使用终端节点获取有关存储在 .httpexchangesHttpExchangeRepository
11. 过程监控
在该模块中,您可以找到两个类来创建通常对进程监控有用的文件:spring-boot
-
ApplicationPidFileWriter创建一个包含应用程序 PID 的文件(默认情况下,在文件名为 ) 的应用程序目录中。application.pid -
WebServerPortFileWriter创建一个包含正在运行的 Web 服务器端口的文件(默认情况下,在文件名为 的应用程序目录中)。application.port
默认情况下,这些写入器未激活,但您可以启用它们:
12. Cloud Foundry 支持
Spring Boot 的 actuator 模块包括额外的支持,当您部署到兼容的 Cloud Foundry 实例时,将激活这些支持。
该路径为所有 bean 提供了替代的安全路由。/cloudfoundryapplication@Endpoint
扩展支持允许使用 Spring Boot 执行器信息来增强 Cloud Foundry 管理 UI(例如可用于查看已部署应用程序的 Web 应用程序)。 例如,应用程序状态页面可以包含完整的运行状况信息,而不是典型的“正在运行”或“已停止”状态。
普通用户无法直接访问该路径。
要使用终端节点,您必须在请求中传递有效的 UAA 令牌。/cloudfoundryapplication |
12.1. 禁用扩展的 Cloud Foundry Actuator 支持
如果要完全禁用终端节点,可以将以下设置添加到您的文件中:/cloudfoundryapplicationapplication.properties
management.cloudfoundry.enabled=false
management:
cloudfoundry:
enabled: false
12.2. Cloud Foundry 自签名证书
默认情况下,端点的安全验证会对各种 Cloud Foundry 服务进行 SSL 调用。
如果您的 Cloud Foundry UAA 或 Cloud Controller 服务使用自签名证书,则需要设置以下属性:/cloudfoundryapplication
management.cloudfoundry.skip-ssl-validation=true
management:
cloudfoundry:
skip-ssl-validation: true
12.3. 自定义上下文路径
如果服务器的 context-path 已配置为 以外的任何内容,则 Cloud Foundry 端点在应用程序的根目录中不可用。
例如,如果 中的 Cloud Foundry 端点在 上可用。/server.servlet.context-path=/app/app/cloudfoundryapplication/*
如果您希望 Cloud Foundry 端点始终在 上可用,而不管服务器的上下文路径如何,则需要在应用程序中显式配置它。
配置会有所不同,具体取决于所使用的 Web 服务器。
对于 Tomcat,您可以添加以下配置:/cloudfoundryapplication/*
@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) {
// Remove underlying context path first (e.g. Servlet container)
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> {
// Remove underlying context path first (e.g. Servlet container)
val path = request.path.pathWithinApplication().value()
return if (path.startsWith("/cloudfoundryapplication")) {
delegate.handle(request, response)
} else {
contextPathDelegate.handle(request, response)
}
}
}
}