# 可投入生产的功能

Spring 启动包括许多额外的功能，以帮助你在将应用程序推向生产时监视和管理该应用程序。你可以选择通过使用 HTTP 端点或使用 JMX 来管理和监视你的应用程序。审核、健康和度量收集也可以自动应用到你的应用程序中。

## 1. 启用可用于生产的功能

[`spring-boot-actuator`]（https://github.com/ Spring-projects/ Spring-boot/tree/v2.6.4/ Spring-boot-project/ Spring-boot-actuator）模块提供了 Spring boot 的所有生产就绪功能。推荐的启用这些特性的方法是添加对`spring-boot-starter-actuator`“starter”的依赖关系。

执行器的定义

执行器是一个制造术语，指用于移动或控制某物的机械设备。执行器可以从微小的变化中产生大量的运动。

要将执行器添加到基于 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 启动包括许多内置的端点，并允许你添加自己的端点。例如，`health`端点提供了基本的应用程序健康信息。

你可以[启用或禁用](#actuator.endpoints.enabling)每个单独的端点和[通过 HTTP 或 JMX 公开它们（使它们可以远程访问）](#actuator.endpoints.exposing)。当端点被启用和公开时，它被认为是可用的。内置端点只有在可用时才会自动配置。大多数应用程序选择的是公开而不是 HTTP，在 HTTP 中，端点的 ID 和`/actuator`的前缀被映射到一个 URL。例如，默认情况下，`health`端点映射到`/actuator/health`。

|   |要了解有关执行器端点及其请求和响应格式的更多信息，请参见单独的 API 文档（[HTML](https://docs.spring.io/spring-boot/docs/2.6.4/actuator-api/htmlsingle)或[PDF](https://docs.spring.io/spring-boot/docs/2.6.4/actuator-api/pdf/spring-boot-actuator-web-api.pdf)）。|
|---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

以下是与技术无关的端点：

|        ID        |说明|
|------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|`auditevents`|公开当前应用程序的审计事件信息。<br/>需要`AuditEventRepository` Bean。|
|`beans`|显示应用程序中所有 Spring bean 的完整列表。|
|`caches`|公开可用的缓存。|
|`conditions`|显示在配置和自动配置类上评估的条件，以及它们匹配或不匹配的原因。|
|`configprops`|显示所有`@Configuration属性`的已整理列表。|
|`env`|公开 Spring 的`ConfigurableEnvironment`中的属性。|
|`flyway`|显示已应用的任何 Flyway 数据库迁移。<br/>需要一个或多个`Flyway`bean。|
|`health`|显示应用程序的健康信息。|
|`httptrace`|显示 HTTP 跟踪信息（默认情况下，最近 100 次 HTTP 请求-响应交换）。<br/>需要`HttpTraceRepository` Bean。|
|`info`|显示任意的应用程序信息。|
|`integrationgraph`|显示 Spring 积分图。<br/>需要对`spring-integration-core`的依赖关系。|
|`loggers`|显示并修改应用程序中记录器的配置。|
|`liquibase`|显示已应用的任何 Liquibase 数据库迁移。<br/>需要一个或多个`Liquibase`bean。|
|`metrics`|显示当前应用程序的“度量”信息。|
|`mappings`|显示所有`@RequestMapping`路径的已整理列表。|
|`quartz`|显示有关 Quartz 调度程序作业的信息。|
|`scheduledtasks`|显示应用程序中的计划任务。|
|`sessions`|允许从 Spring 会话支持的会话存储中检索和删除用户会话。<br/>需要使用 Spring 会话的基于 Servlet 的 Web 应用程序。|
|`shutdown`|让应用程序优雅地关闭。<br/>默认禁用。|
|`startup`|显示由`ApplicationStartup`收集的[启动步骤数据](features.html#features.spring-application.startup-tracking)。<br/>需要将`SpringApplication`配置为`BufferingApplicationStartup`。|
|`threaddump`|执行线程转储。|

如果你的应用程序是一个 Web 应用程序（ Spring MVC、 Spring WebFlux 或 Jersey），则可以使用以下附加端点：

|     ID     |说明|
|------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `heapdump` |返回堆转储文件。<br/>在热点 JVM 上，将返回一个`HPROF`-format 文件。<br/>在 OpenJ9JVM 上，将返回一个`PHD`-format 文件。|
| `jolokia`  |当 Jolokia 在 Classpath 上时，在 HTTP 上公开 JMX Bean（WebFlux 不可用）。<br/>需要依赖于`jolokia-core`。|
| `logfile`  |返回日志文件的内容（如果设置了`logging.file.name`或`logging.file.path`属性）。<br/>支持使用 http`Range`头来检索日志文件的部分内容。|
|`prometheus`|以 Prometheus 服务器可以抓取的格式公开度量数据。<br/>需要对`micrometer-registry-prometheus`具有依赖关系。|

### 2.1.启用端点

默认情况下，除了`shutdown`之外的所有端点都已启用。要配置端点的启用，请使用其`management.endpoint.<id>.enabled`属性。下面的示例启用`shutdown`端点：

属性

```
management.endpoint.shutdown.enabled=true
```

Yaml

```
management:
  endpoint:
    shutdown:
      enabled: true
```

如果你希望端点使能是 OPT 输入而不是 OPT 输出，那么将`management.endpoints.enabled-by-default`属性设置为`false`，并使用单独的端点`enabled`属性来 OPT 返回。下面的示例启用`info`端点并禁用所有其他端点：

属性

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

Yaml

```
management:
  endpoints:
    enabled-by-default: false
  endpoint:
    info:
      enabled: true
```

|   |已禁用的端点将从应用程序上下文中完全删除。<br/>如果只想更改公开端点的技术，请使用[`include`和`exclude`属性]（#actuator.endpoints.explosing）。|
|---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

### 2.2.公开端点

由于端点可能包含敏感信息，因此你应该仔细考虑何时公开它们。下表显示了内建端点的默认暴露：

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

要更改暴露的端点，请使用以下特定于技术的`include`和`exclude`属性：

|财产|Default |
|-------------------------------------------|--------|
|`management.endpoints.jmx.exposure.exclude`|        |
|`management.endpoints.jmx.exposure.include`|  `*`   |
|`management.endpoints.web.exposure.exclude`|        |
|`management.endpoints.web.exposure.include`|`health`|

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

例如，要停止在 JMX 上公开所有端点，而只公开`health`和`info`端点，请使用以下属性：

属性

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

Yaml

```
management:
  endpoints:
    jmx:
      exposure:
        include: "health,info"
```

`*`可用于选择所有端点。例如，要在 HTTP 上公开除了`env`和`beans`端点之外的所有内容，请使用以下属性：

属性

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

Yaml

```
management:
  endpoints:
    web:
      exposure:
        include: "*"
        exclude: "env,beans"
```

|   |`*`在 YAML 中具有特殊的含义，因此，如果你想包含（或排除）所有端点，请务必添加引号。|
|---|-----------------------------------------------------------------------------------------------------------------------|

|   |如果你的应用程序公开，我们强烈建议你也[保护你的端点](#actuator.endpoints.security)。|
|---|-----------------------------------------------------------------------------------------------------------------------------------|

|   |如果你希望实现自己的端点公开策略，则可以注册`EndpointFilter` Bean。|
|---|---------------------------------------------------------------------------------------------------------------------|

### 2.3.安全

出于安全目的，除`/health`以外的所有执行器都默认禁用。你可以使用`management.endpoints.web.exposure.include`属性来启用执行器。

|   |在设置`management.endpoints.web.exposure.include`之前，请确保暴露的执行器不包含敏感信息，通过将它们放置在防火墙后面来进行安全保护，或者通过 Spring 之类的安全性来进行安全保护。|
|---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

如果 Spring 安全性在 Classpath 上，并且不存在其他`WebSecurityConfigurerAdapter`或`SecurityFilterChain` Bean，则除`/health`以外的所有致动器都由 Spring 引导自动配置来保护。如果你定义了自定义的`WebSecurityConfigurerAdapter`或`SecurityFilterChain` Bean， Spring 引导自动配置就会后退，并允许你完全控制执行器访问规则。

如果你希望为 HTTP 端点配置自定义安全性（例如，仅允许具有特定角色的用户访问它们）， Spring Boot 提供了一些方便的`RequestMatcher`对象，你可以将这些对象与 Spring 安全性结合使用。

典型的 Spring 安全配置可能类似于以下示例：

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

@Configuration(proxyBeanMethods = false)
public class MySecurityConfiguration {

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

}

```

前面的示例使用`EndpointRequest.toAnyEndpoint()`将请求匹配到任何端点，然后确保所有请求都具有`ENDPOINT_ADMIN`角色。在`EndpointRequest`上也可以使用其他几种匹配方法。有关详细信息，请参见 API 文档（[HTML](https://docs.spring.io/spring-boot/docs/2.6.4/actuator-api/htmlsingle)或[PDF](https://docs.spring.io/spring-boot/docs/2.6.4/actuator-api/pdf/spring-boot-actuator-web-api.pdf)）。

如果你将应用程序部署在防火墙之后，那么你可能希望你的所有执行器端点都可以访问，而无需进行身份验证。你可以通过更改`management.endpoints.web.exposure.include`属性来实现此目的，如下所示：

属性

```
management.endpoints.web.exposure.include=*
```

Yaml

```
management:
  endpoints:
    web:
      exposure:
        include: "*"
```

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

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

@Configuration(proxyBeanMethods = false)
public class MySecurityConfiguration {

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

}

```

|   |在上述两个示例中，配置仅适用于执行器端点。<br/>由于 Spring boot 的安全配置在存在任何`SecurityFilterChain` Bean 的情况下完全退缩，因此需要配置一个附加的`SecurityFilterChain` Bean，其规则适用于应用程序的其余部分。|
|---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

#### 2.3.1.跨站点请求伪造保护

由于 Spring boot 依赖于 Spring Security 的默认值，因此 CSRF 保护在默认情况下是打开的。这意味着要求执行器端点`POST`（关机和记录器端点）、`PUT`或`DELETE`的端点在使用默认安全配置时会得到 403（禁止）错误。

|   |我们建议仅当你正在创建一个由非浏览器客户端使用的服务时，才完全禁用 CSRF 保护。|
|---|-------------------------------------------------------------------------------------------------------------------------|

你可以在[Spring Security Reference Guide](https://docs.spring.io/spring-security/reference/5.6.2/features/exploits/csrf.html)中找到有关 CSRF 保护的其他信息。

### 2.4.配置端点

端点自动缓存响应，以读取不接受任何参数的操作。要配置端点缓存响应的时间长度，请使用其`cache.time-to-live`属性。下面的示例将`beans`端点缓存的持续时间设置为 10 秒：

属性

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

Yaml

```
management:
  endpoint:
    beans:
      cache:
        time-to-live: "10s"
```

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

### 2.5.用于执行器 Web 端点的超媒体

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

要禁用“发现页面”，请将以下属性添加到应用程序属性中：

属性

```
management.endpoints.web.discovery.enabled=false
```

Yaml

```
management:
  endpoints:
    web:
      discovery:
        enabled: false
```

在配置自定义管理上下文路径时，“发现页”会自动从`/actuator`移动到管理上下文的根。例如，如果管理上下文路径是`/management`，则可以从`/management`获取发现页面。当管理上下文路径设置为`/`时，将禁用发现页，以防止与其他映射发生冲突的可能性。

### 2.6.CORS 支持

[跨源资源共享](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing)是一个[W3C 规范](https://www.w3.org/TR/cors/)，它允许你以灵活的方式指定授权哪种类型的跨域请求。如果使用 Spring MVC 或 Spring WebFlux，则可以配置 Actuator 的 Web 端点以支持此类场景。

默认情况下，CORS 支持是禁用的，并且只有在你设置了`management.endpoints.web.cors.allowed-origins`属性后才会启用。以下配置允许`GET`和`POST`来自`example.com`域的调用：

属性

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

Yaml

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

|   |参见[`CorsEndpoint属性`]（https://github.com/ Spring-projects/ Spring-boot/tree/v2.6.4/ Spring-boot-project/ Spring-boot-actuator-autofigure/SRC/main/java/org/springframework/boot/actuate/autofigure/endpoint/web/corsendpointproperties.java）以获取完整的选项列表。|
|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

### 2.7.实现自定义端点

如果添加带有`@Bean`注释的`@Endpoint`，则任何带有`@ReadOperation`、`@WriteOperation`或`@DeleteOperation`注释的方法都会在 JMX 上自动公开，在 Web 应用程序中，也会在 HTTP 上自动公开。可以通过使用 Jersey、 Spring MVC 或 Spring WebFlux 在 HTTP 上公开端点。如果球衣和 Spring MVC 都可用，则使用 Spring MVC。

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

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

```

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

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

最后，如果需要访问特定于 Web Framework 的功能，则可以实现 Servlet 或 Spring `@Controller`和`@RestController`端点，但代价是它们不能在 JMX 上或在使用不同的 Web 框架时可用。

#### 2.7.1.接收输入

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

你可以将 JSON 请求主体中的每个根属性映射到端点的参数。考虑以下 JSON 请求主体：

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

你可以使用它来调用一个包含`String name`和`int counter`参数的写操作，如下例所示：

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

```

|   |由于端点与技术无关，因此只能在方法签名中指定简单的类型。<br/>特别是，声明带有`CustomData`类型的单个参数，该类型定义了`name`和`counter`属性，不受支持。|
|---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

|   |为了让输入映射到操作方法的参数，实现端点的 Java 代码应该使用`-parameters`进行编译，实现端点的代码应该用`-java-parameters`编译。<br/>如果你使用 Spring boot 的 Gradle 插件，或者如果你使用 Maven 和`spring-boot-starter-parent`，这将自动发生。|
|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

##### 输入类型转换

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

#### 2.7.2.自定义 Web 端点

对`@Endpoint`、`@WebEndpoint`或`@EndpointWebExtension`的操作使用 Jersey、 Spring MVC 或 Spring WebFlux 在 HTTP 上自动公开。如果球衣和 Spring MVC 都可用，则使用 Spring MVC。

##### Web 端点请求谓词

对于公开 Web 的端点上的每个操作，都会自动生成一个请求谓词。

##### 路径

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

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

##### HTTP 方法

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

|操作|HTTP method|
|------------------|-----------|
|`@ReadOperation`|   `GET`   |
|`@WriteOperation`|  `POST`   |
|`@DeleteOperation`| `DELETE`  |

##### 消耗

对于使用请求主体的`@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（确定）。如果它不返回一个值，响应状态将是 204（没有内容）。

如果调用的操作没有所需的参数或参数不能转换为所需的类型，则不调用该操作方法，响应状态将为 400（错误请求）。

##### Web 端点范围请求

你可以使用 HTTP 范围请求来请求 HTTP 资源的一部分。当使用 Spring MVC 或 Spring Web 流量时，返回`org.springframework.core.io.Resource`的操作自动支持范围请求。

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

##### Web 端点安全

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

#### 2.7.3. Servlet 端点

Servlet 可以通过实现一个用`@ServletEndpoint`注释的类来公开一个端点，该类也实现`Supplier<EndpointServlet>`。 Servlet 端点提供了与 Servlet 容器的更深的集成，但以牺牲可移植性为代价。它们旨在用于将现有的 Servlet 作为端点公开。对于新的端点，应尽可能使用`@Endpoint`和`@WebEndpoint`注释。

#### 2.7.4.控制器端点

可以使用`@ControllerEndpoint`和`@RestControllerEndpoint`来实现仅由 Spring MVC 或 Spring WebFlux 公开的端点。方法通过使用 Spring MVC 和 Spring WebFlux 的标准注释进行映射，例如`@RequestMapping`和`@GetMapping`，并使用端点的 ID 作为路径的前缀。控制器端点提供了与 Spring 的 Web 框架的更深入集成，但以牺牲可移植性为代价。只要有可能，就应该首选`@Endpoint`和`@WebEndpoint`注释。

### 2.8.健康信息

你可以使用健康信息来检查正在运行的应用程序的状态。当生产系统发生故障时，监控软件经常使用它来提醒某人。由`health`端点公开的信息取决于`management.endpoint.health.show-details`和`management.endpoint.health.show-components`属性，这些属性可以配置为以下值之一：

|      Name       |说明|
|-----------------|-------------------------------------------------------------------------------------------------------------------------------|
|     `never`     |细节从未显示。|
|`when-authorized`|详细信息仅显示给授权用户。<br/>授权角色可以通过使用`management.endpoint.health.roles`进行配置。|
|    `always`     |详细信息将向所有用户显示。|

默认值为`never`。当用户处于端点的一个或多个角色中时，该用户被视为获得授权。如果端点没有配置的角色（缺省），则所有经过身份验证的用户都被认为是经过授权的。你可以使用`management.endpoint.health.roles`属性来配置角色。

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

健康信息是从一个[`HealthContributorRegistry`]（https://github.com/ Spring-projects/ Spring-boot/tree/v2.6.4/ Spring-boot-project/ Spring-boot-actuator/SRC/main/java/java/org/org/org/org/org/SpringtorFramework/boot/Actuate/health/HealthtorRegistry.java）的内容中收集的（默认情况下，所有[<gt r=“388”/[gtHub/ Spring-gitHub.com/ Spring-projects/ Spring-tree/ Spring- Spring 启动包括一些自动配置的`HealthContributors`，并且还可以编写自己的。

a`HealthContributor`可以是 a`HealthIndicator`，也可以是 a`CompositeHealthContributor`。a`HealthIndicator`提供实际的健康信息，包括 a`Status`。a`CompositeHealthContributor`提供了其它`HealthContributors`的复合。总的来说，贡献者形成了一个树状结构来表示整个系统的健康状况。

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

|   |你可以使用`HealthContributorRegistry`在运行时注册和取消注册健康指标。|
|---|----------------------------------------------------------------------------------------------------|

#### 2.8.1.自动配置的健康指示器

在适当的时候， Spring 引导自动配置下表中列出的`HealthIndicators`。你还可以通过配置`management.health.key.enabled`来启用或禁用选定的指示器，下表列出了`key`:

|      Key      |姓名|                       Description                       |
|---------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------|
|  `cassandra`  |[`CassandraDriverHealthIndicator`]（https://github.com/ Spring-projects/ Spring-boot/tree/v2.6.4/ Spring-boot-project/ Spring-boot-actuator/SRC/main/java/org/springframework/boot/actuate/actuate/cassandra/cassandradriverhealthindicator.java）|         Checks that a Cassandra database is up.         |
|  `couchbase`  |[`CouchbaseHealthIndicator`]（https://github.com/ Spring-projects/ Spring-boot/tree/v2.6.4/ Spring-boot-project/ Spring-boot-actuator/SRC/main/java/org/springframework/boot/actuate/actuate/couchbase/couchbasehealthindicator.java）|         Checks that a Couchbase cluster is up.          |
|     `db`      |[`DataSourceHealthIndicator`]（https://github.com/ Spring-projects/ Spring-boot/tree/v2.6.4/ Spring-boot-project/ Spring-boot-actuator/SRC/main/java/org/springframework/boot/actuate/actuate/jdbc/dasourcehealthindicator.java）|Checks that a connection to `DataSource` can be obtained.|
|  `diskspace`  |[`DiskSpaceHealthIndicator`]（https://github.com/ Spring-projects/ Spring-boot/tree/v2.6.4/ Spring-boot-project/ Spring-boot-actuator/SRC/main/java/org/springframework/boot/actuate/actuate/system/diskspacehealthindicator.java）|               Checks for low disk space.                |
|`elasticsearch`|[`ElasticsearchRestHealthIndicator`]（https://github.com/ Spring-projects/ Spring-boot/tree/v2.6.4/ Spring-boot-project/ Spring-boot-actuator/SRC/main/java/org/org/springframework/boot/actuate/elasticsearch/elasticsearch/elasticsearchsethalthindicator.java）|       Checks that an Elasticsearch cluster is up.       |
|  `hazelcast`  |[`HazelcastHealthIndicator`]（https://github.com/ Spring-projects/ Spring-boot/tree/v2.6.4/ Spring-boot-project/ Spring-boot-actuator/SRC/main/java/org/springframework/boot/actuate/actuate/hazelcast/hazelcasthealthindicator.java）|          Checks that a Hazelcast server is up.          |
|  `influxdb`   |[`InfluxDbHealthIndicator`]（https://github.com/ Spring-projects/ Spring-boot/tree/v2.6.4/ Spring-boot-project/ Spring-boot-actuator/SRC/main/java/org/org/springframework/boot/actuate/inflation/influxdbhealthindicator.java）|          Checks that an InfluxDB server is up.          |
|     `jms`     |[`JmsHealthIndicator`]（https://github.com/ Spring-projects/ Spring-boot/tree/v2.6.4/ Spring-boot-project/ Spring-boot-actuator/SRC/main/java/org/springframework/boot/actuate/actuate/jms/jmshealthindicator.java）|             Checks that a JMS broker is up.             |
|    `ldap`     |[`LdapHealthIndicator`]（https://github.com/ Spring-projects/ Spring-boot/tree/v2.6.4/ Spring-boot-project/ Spring-boot-actuator/SRC/main/java/org/springframework/boot/actuate/actuate/ldap/ldaphealthindicator.java）|            Checks that an LDAP server is up.            |
|    `mail`     |[`MailHealthIndicator`]（https://github.com/ Spring-projects/ Spring-boot/tree/v2.6.4/ Spring-boot-project/ Spring-boot-actuator/SRC/main/java/org/springframework/boot/actuate/mail/mailhealthindicator.java）|            Checks that a mail server is up.             |
|    `mongo`    |[`MongoHealthIndicator`]（https://github.com/ Spring-projects/ Spring-boot/tree/v2.6.4/ Spring-boot-project/ Spring-boot-actuator/SRC/main/java/org/springframework/boot/actuate/actuate/mongo/mongohealthindicator.java）|           Checks that a Mongo database is up.           |
|    `neo4j`    |[`Neo4jHealthIndicator`]（https://github.com/ Spring-projects/ Spring-boot/tree/v2.6.4/ Spring-boot-project/ Spring-boot-actuator/SRC/main/java/org/springframework/boot/actuate/actuate/NEO4j/NEO4jhealthindicator.java）|           Checks that a Neo4j database is up.           |
|    `ping`     |[`PingHealthIndicator`]（https://github.com/ Spring-projects/ Spring-boot/tree/v2.6.4/ Spring-boot-project/ Spring-boot-actuator/SRC/main/java/org/springframework/boot/actuate/health/pinghealthindicator.java）|               Always responds with `UP`.                |
|   `rabbit`    |[`RabbitHealthIndicator`]（https://github.com/ Spring-projects/ Spring-boot/tree/v2.6.4/ Spring-boot-project/ Spring-boot-actuator/SRC/main/java/org/springframework/boot/actuate/amqp/rabbithalthindicator.java）|           Checks that a Rabbit server is up.            |
|    `redis`    |[`RedisHealthIndicator`]（https://github.com/ Spring-projects/ Spring-boot/tree/v2.6.4/ Spring-boot-project/ Spring-boot-actuator/SRC/main/java/org/springframework/boot/actuate/redis/redishealthindicator.java）|            Checks that a Redis server is up.            |
|    `solr`     |[`SolrHealthIndicator`]（https://github.com/ Spring-projects/ Spring-boot/tree/v2.6.4/ Spring-boot-project/ Spring-boot-actuator/SRC/main/java/org/springframework/boot/actuate/actuate/SOLR/solrhealthindicator.java）|            Checks that a Solr server is up.             |

|   |你可以通过设置`management.health.defaults.enabled`属性来禁用它们。|
|---|--------------------------------------------------------------------------------------|

其他`HealthIndicators`可用，但默认情况下未启用：

|      Key       |姓名|                      Description                      |
|----------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------|
|`livenessstate` |[`LivenessStateHealthIndicator`]（https://github.com/ Spring-projects/ Spring-boot/tree/v2.6.4/ Spring-boot-project/ Spring-boot-actuator/SRC/main/java/org/springframework/boot/actuate/availability/livenessstatehealthindicator.java）|Exposes the “Liveness” application availability state. |
|`readinessstate`|[`ReadinessStateHealthIndicator`]（https://github.com/ Spring-projects/ Spring-boot/tree/v2.6.4/ Spring-boot-project/ Spring-boot-actuator/SRC/main/java/org/springframework/boot/actuate/availability/readinessstatehealthindicator.java）|Exposes the “Readiness” application availability state.|

#### 2.8.2.编写自定义健康指示器

要提供自定义健康信息，你可以注册实现[`HealthIndicator`]（https://github.com/ Spring-projects/ Spring-boot/tree/v2.6.4/ Spring-boot-project/ Spring-boot-actuator/SRC/main/java/org/springframework/boot/actuate/health/healthindicator.java）接口的 Spring bean。你需要提供`health()`方法的一个实现，并返回一个`Health`响应。`Health`响应应该包括状态，并且可以选择包括要显示的附加细节。下面的代码显示了`HealthIndicator`实现的示例：

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

@Component
public class MyHealthIndicator implements HealthIndicator {

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

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

}

```

|   |给定的`HealthIndicator`的标识符是没有`HealthIndicator`后缀的 Bean 的名称，如果它存在的话。<br/>在前面的示例中，在名为`my`的条目中，健康信息是可用的。|
|---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

除了 Spring boot 的预定义[`Status`]（https://github.com/ Spring-projects/ Spring-boot/tree/v2.6.4/ Spring-boot-project/ Spring-boot-actuator/SRC/main/java/org/springframework/boot/actuate/actuate/health/status.java）类型外，`Health`还可以返回一个代表新系统状态的自定义`Status`。在这种情况下，你还需要提供[`StatusAggregator`]（https://github.com/ Spring-projects/ Spring-boot/tree/v2.6.4/ Spring-boot-project/ Spring-boot-actuator/SRC/main/java/org/org/springframework/boot/actuate/actuate/health/statusaggregator.javator.java）接口的自定义实现，或者你必须使用<gtr=“440”配置属性来配置默认实现。

例如，假设一个新的`Status`代码为`FATAL`的`HealthIndicator`正在你的一个`HealthIndicator`实现中使用。要配置严重性顺序，请将以下属性添加到应用程序属性中：

属性

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

Yaml

```
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
```

Yaml

```
management:
  endpoint:
    health:
      status:
        http-mapping:
          down: 503
          fatal: 503
          out-of-service: 503
```

|   |如果需要更多的控制，可以定义自己的`HttpCodeStatusMapper` Bean。|
|---|------------------------------------------------------------------------------|

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

|     Status     |映射|
|----------------|----------------------------------------------|
|     `DOWN`     |`SERVICE_UNAVAILABLE`(`503`)|
|`OUT_OF_SERVICE`|`SERVICE_UNAVAILABLE`(`503`)|
|      `UP`      |默认情况下没有映射，所以 HTTP 状态是`200`|
|   `UNKNOWN`    |默认情况下没有映射，所以 HTTP 状态是`200`|

#### 2.8.3.反应性健康指标

对于反应性应用程序，例如那些使用 Spring WebFlux 的应用程序，`ReactiveHealthContributor`提供了用于获取应用程序健康状态的非阻塞契约。与传统的`HealthContributor`类似，健康信息是从一个[`ReactiveHealthContributorRegistry`]（https://github.com/ Spring-projects/ Spring-boot/tree/v2.6.4/ Spring-boot-project/ Spring-boot-project/ Spring-boot-actuator/SRC/main/java/org/org/springframework/boot/actuate/actuate/actuate/health/health/reform/regram/reactuate/reactuatorregistry/registry/registry/registry/registry 常规的`HealthContributors`在弹性计划程序上执行，它们不会根据反应性 API 进行检查。

|   |在反应性应用程序中，你应该使用`ReactiveHealthContributorRegistry`在运行时注册和取消注册健康指标。<br/>如果你需要注册一个常规的`HealthContributor`，你应该用`ReactiveHealthContributor#adapt`包装它。|
|---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

要从反应性 API 提供自定义的健康信息，你可以注册实现[`ReactiveHealthIndicator`]（https://github.com/ Spring-projects/ Spring-boot/tree/v2.6.4/ Spring-boot-project/ Spring-boot-actuator/SRC/main/java/org/springframework/boot/actuate/actuate/healthindicator.java）接口的 Spring bean。下面的代码显示了`ReactiveHealthIndicator`实现的示例：

```
import reactor.core.publisher.Mono;

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

@Component
public class MyReactiveHealthIndicator implements ReactiveHealthIndicator {

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

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

}

```

|   |要自动处理该错误，请考虑从`AbstractReactiveHealthIndicator`扩展。|
|---|---------------------------------------------------------------------------------------------|

#### 2.8.4.自动配置的 reactivehealthindicators###

在适当的时候， Spring 引导自动配置以下`ReactiveHealthIndicators`:

|      Key      |姓名|                Description                |
|---------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------|
|  `cassandra`  |[`CassandraDriverReactiveHealthIndicator`]（https://github.com/ Spring-projects/ Spring-boot/tree/v2.6.4/ Spring-boot-project/ Spring-boot-actuator/SRC/main/java/org/springframework/boot/actuate/actuate/cassandra/cassandradriverreactivehealthindicator.java）|  Checks that a Cassandra database is up.  |
|  `couchbase`  |[`CouchbaseReactiveHealthIndicator`]（https://github.com/ Spring-projects/ Spring-boot/tree/v2.6.4/ Spring-boot-project/ Spring-boot-actuator/SRC/main/java/org/springframework/boot/actuate/actuate/couchbase/couchbase/couchbasereactivehealthindicator.jav|  Checks that a Couchbase cluster is up.   |
|`elasticsearch`|[`ElasticsearchReactiveHealthIndicator`]（https://github.com/ Spring-projects/ Spring-boot/tree/v2.6.4/ Spring-boot-project/ Spring-boot-actuator/SRC/main/java/org/springframework/boot/actuate/elasticsearch/elasticsearch/elasticsearchreactivehealthindicator.java）|Checks that an Elasticsearch cluster is up.|
|    `mongo`    |[`MongoReactiveHealthIndicator`]（https://github.com/ Spring-projects/ Spring-boot/tree/v2.6.4/ Spring-boot-project/ Spring-boot-actuator/SRC/main/java/org/springframework/boot/actuate/actuate/mongo/mongoreactivehealthindicator.java）|    Checks that a Mongo database is up.    |
|    `neo4j`    |[`Neo4jReactiveHealthIndicator`]（https://github.com/ Spring-projects/ Spring-boot/tree/v2.6.4/ Spring-boot-project/ Spring-boot-actuator/SRC/main/java/org/springframework/boot/actuate/actuate/NEO4j/NEO4jreactivehealthindicator.java）|    Checks that a Neo4j database is up.    |
|    `redis`    |[`RedisReactiveHealthIndicator`]（https://github.com/ Spring-projects/ Spring-boot/tree/v2.6.4/ Spring-boot-project/ Spring-boot-actuator/SRC/main/java/org/springframework/boot/actuate/redis/redisreactivehealthindicator.java）|     Checks that a Redis server is up.     |

|   |如果有必要，用反应性指示器代替常规指示器。<br/>此外，任何未显式处理的`HealthIndicator`都会自动包装。|
|---|----------------------------------------------------------------------------------------------------------------------------------------------------|

#### 2.8.5.健康团体

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

要创建健康指示剂组，可以使用`management.endpoint.health.group.<name>`属性，并将健康指示剂 ID 的列表指定为`include`或`exclude`。例如，要创建一个只包含数据库指标的组，你可以定义以下内容：

属性

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

Yaml

```
management:
  endpoint:
    health:
      group:
        custom:
          include: "db"
```

然后，你可以点击`[localhost:8080/actuator/health/custom](http://localhost:8080/actuator/health/custom)`检查结果。

类似地，要创建一个从组中排除数据库指标并包括所有其他指标的组，你可以定义以下内容：

属性

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

Yaml

```
management:
  endpoint:
    health:
      group:
        custom:
          exclude: "db"
```

默认情况下，组继承与系统健康相同的`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
```

Yaml

```
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")`bean。|
|---|-----------------------------------------------------------------------------------------------------------------------------------------------|

健康组还可以包括/排除`CompositeHealthContributor`。你也可以只包含/排除`CompositeHealthContributor`中的某个组件。这可以使用组件的完全限定名称来完成，如下所示：

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

在上面的示例中，`custom`组将包括名为`HealthContributor`的`primary`，这是组合`test`的一个组件。在这里，`primary`本身是一个组合，而名称为`b`的`HealthContributor`将被排除在`custom`组之外。

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

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

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

#### 2.8.6.数据源健康

`DataSource`健康指示器显示标准数据源和路由数据源 bean 的健康状况。路由数据源的健康状况包括其每个目标数据源的健康状况。在健康端点的响应中，每个路由数据源的目标都是通过使用其路由密钥来命名的。如果不希望在指示器的输出中包含路由数据源，请将`management.health.db.ignore-routing-data-sources`设置为`true`。

### 2.9.Kubernetes 探测器

部署在 Kubernetes 上的应用程序可以用[容器探针](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes)提供有关其内部状态的信息。根据[你的 Kubernetes 配置](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/)，Kubelet 调用这些探测并对结果做出反应。

默认情况下， Spring boot 管理你的[应用程序可用性状态](features.html#features.spring-application.application-availability)。如果部署在 Kubernetes 环境中，致动器将从`ApplicationAvailability`接口收集“活性”和“就绪”信息，并在专用[健康指标](#actuator.endpoints.health.auto-configured-health-indicators)中使用该信息：`LivenessStateHealthIndicator`和`ReadinessStateHealthIndicator`。这些指标显示在全球健康端点（`"/actuator/health"`）上。通过使用[健康团体](#actuator.endpoints.health.groups):`"/actuator/health/liveness"`和`"/actuator/health/readiness"`，它们也可以作为单独的 HTTP 探针公开。

然后，你可以使用以下端点信息来配置 Kubernetes 基础架构：

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

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

|   |`<actuator-port>`应该设置为执行器端点可用的端口。<br/>如果`"management.server.port"`属性已设置，则它可以是主 Web 服务器端口或单独的管理端口。|
|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

只有当应用程序[在 Kubernetes 环境中运行](deployment.html#deployment.cloud.kubernetes)时，这些健康组才会自动启用。你可以通过使用`management.endpoint.health.probes.enabled`配置属性在任何环境中启用它们。

|   |如果一个应用程序的启动时间超过了配置的活动周期，Kubernetes 提到`"startupProbe"`是一个可能的解决方案。<br/>这里不一定需要`"startupProbe"`，因为`"readinessProbe"`在完成所有启动任务之前都会失败。参见描述[探针在应用程序生命周期中的行为](#actuator.endpoints.kubernetes-probes.lifecycle)的部分。|
|---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

如果你的执行器端点部署在单独的管理上下文中，那么端点不使用与主应用程序相同的 Web 基础设施（端口、连接池、框架组件）。在这种情况下，即使主应用程序不能正常工作（例如，它不能接受新的连接），探测检查也可能是成功的。出于这个原因，在主服务器端口上启用`liveness`和`readiness`健康组是一个好主意。这可以通过设置以下属性来完成：

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

这将使`liveness`在主服务器端口上的`/livez`和`readiness`上可用。

#### 2.9.1.用 Kubernetes 探测器检查外部状态 ###

Actuator 将“活性”和“准备”探测配置为健康小组。这意味着所有的[健康团体功能](#actuator.endpoints.health.groups)对它们都是可用的。例如，你可以配置其他的健康指标：

属性

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

Yaml

```
management:
  endpoint:
    health:
      group:
        readiness:
          include: "readinessState,customCheck"
```

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

“活性”调查不应依赖于外部系统的健康检查。如果[应用程序的活性状态](features.html#features.spring-application.application-availability.liveness)被破坏，Kubernetes 将尝试通过重新启动应用程序实例来解决该问题。这意味着，如果外部系统（例如数据库、Web API 或外部缓存）发生故障，Kubernetes 可能会重新启动所有应用程序实例并产生级联故障。

至于“就绪”调查，检查外部系统的选择必须由应用程序开发人员仔细做出。出于这个原因， Spring 引导不包括在准备状态探测中的任何额外的健康检查。如果[应用程序实例的准备状态](features.html#features.spring-application.application-availability.readiness)未准备好，Kubernetes 不会将通信量路由到该实例。一些外部系统可能不会被应用程序实例共享，在这种情况下，它们可能会被包含在就绪状态探测中。其他外部系统可能不是应用程序所必需的（应用程序可能有断路器和后备电源），在这种情况下，它们绝对不应该被包括在内。不幸的是，所有应用程序实例共享的外部系统是常见的，你必须做出判断：将其纳入准备状态调查，并期望当外部服务关闭或将其排除在外时，应用程序将退出服务，并处理堆栈中更高的故障，也许通过在呼叫者中使用断路器。

|   |如果应用程序的所有实例都没有准备好，那么带有`type=ClusterIP`或`NodePort`的 Kubernetes 服务不接受任何传入连接。<br/>没有 HTTP 错误响应（503 等），因为没有连接。<br/>带有`type=LoadBalancer`的服务可能接受连接，也可能不接受连接，取决于提供者。<br/>具有显式[ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/)的服务也以某种方式响应这取决于实现——Ingress 服务本身必须决定如何处理来自下游的“拒绝的连接”。<br/>HTTP503 在负载均衡器和 Ingress 的情况下都很有可能发生。|
|---| |

此外，如果一个应用程序使用 Kubernetes[自动缩放](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/)，它可能会对从负载均衡器取出的应用程序做出不同的反应，这取决于它的自动定标器配置。

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

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

Spring 引导发布[启动和关闭过程中的应用程序事件](features.html#features.spring-application.application-events-and-listeners)，并且探测可以侦听这样的事件并公开`AvailabilityState`信息。

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

当 Spring 启动应用程序启动时：

|Startup phase|LivenessState|  ReadinessState   |  HTTP server   |笔记|
|-------------|-------------|-------------------|----------------|--------------------------------------------------------------------------------------------------------------|
|  Starting   |  `BROKEN`   |`REFUSING_TRAFFIC` |  Not started   |Kubernetes 检查“活性”探测，如果时间太长，则重新启动应用程序。|
|   Started   |  `CORRECT`  |`REFUSING_TRAFFIC` |Refuses requests|将刷新应用程序上下文。应用程序执行启动任务，但尚未接收到流量。|
|    Ready    |  `CORRECT`  |`ACCEPTING_TRAFFIC`|Accepts requests|启动任务完成。应用程序正在接收流量。|

当 Spring 引导应用程序关闭时：

| Shutdown phase  |Liveness State|  Readiness State  |       HTTP server       |笔记|
|-----------------|--------------|-------------------|-------------------------|---------------------------------------------------------------------------------------------|
|     Running     |  `CORRECT`   |`ACCEPTING_TRAFFIC`|    Accepts requests     |已请求关闭。|
|Graceful shutdown|  `CORRECT`   |`REFUSING_TRAFFIC` |New requests are rejected|如果启用，[优雅的关机处理飞行中的请求](web.html#web.graceful-shutdown)。|
|Shutdown complete|     N/A      |        N/A        |   Server is shut down   |应用程序上下文是关闭的，应用程序是关闭的。|

|   |有关 Kubernetes 部署的更多信息，请参见[Kubernetes 容器生命周期部分](deployment.html#deployment.cloud.kubernetes.container-lifecycle)。|
|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------|

### 2.10.应用程序信息

应用程序信息公开了从所有[`InfoContributor`]（https://github.com/ Spring-projects/ Spring-boot/tree/v2.6.4/ Spring-boot-project/ Spring-boot-actuator/SRC/main/java/org/org/springframework/boot/actuate/actuate/info/infrocontributor.java）bean 中收集的各种信息，这些 bean 定义在你的<gt Spring 引导包括许多自动配置的`InfoContributor`bean，并且可以编写自己的 bean。

#### 2.10.1.自动配置的信息贡献者

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

|  ID   |姓名|                                Description                                |               Prerequisites                |
|-------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------|--------------------------------------------|
|`build`|[`BuildInfoContributor`]（https://github.com/ Spring-projects/ Spring-boot/tree/v2.6.4/ Spring-boot-project/ Spring-boot-actuator/SRC/main/java/org/SpringFramework/boot/actuate/info/buildinfoContributor.java）|                        Exposes build information.                         |A `META-INF/build-info.properties` resource.|
| `env` |[`EnvironmentInfoContributor`]（https://github.com/ Spring-projects/ Spring-boot/tree/v2.6.4/ Spring-boot-project/ Spring-boot-actuator/SRC/main/java/org/springframework/boot/actuate/info/envirmentinfocontributor.java）|Exposes any property from the `Environment` whose name starts with `info.`.|                   None.                    |
| `git` |[`GitInfoContributor`]（https://github.com/ Spring-projects/ Spring-boot/tree/v2.6.4/ Spring-boot-project/ Spring-boot-actuator/SRC/main/java/org/springframework/boot/actuate/info/gitinfocontributor.javor.java）|                         Exposes git information.                          |        A `git.properties` resource.        |
|`java` |[`JavaInfoContributor`]（https://github.com/ Spring-projects/ Spring-boot/tree/v2.6.4/ Spring-boot-project/ Spring-boot-actuator/SRC/main/java/org/springframework/boot/actuate/actuate/info/javainfocontributor.java）|                     Exposes Java runtime information.                     |                   None.                    |

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

由于没有先决条件表明应该启用它们，`env`和`java`贡献者默认情况下是禁用的。你可以通过将`management.info.env.enabled`或`management.info.java.enabled`属性设置为`true`来启用它们。

默认情况下启用`build`和`git`信息贡献者。可以通过将其`management.info.<id>.enabled`属性设置为`false`来禁用每个属性。或者，要禁用每个默认情况下通常启用的贡献者，请将`management.info.defaults.enabled`属性设置为`false`。

#### 2.10.2.自定义应用程序信息

当`env`contributor 被启用时，你可以通过设置`info.*` Spring 属性来定制由`info`端点公开的数据。在`info`键下的所有`Environment`属性都会自动公开。例如，你可以在`application.properties`文件中添加以下设置：

属性

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

Yaml

```
info:
  app:
    encoding: "UTF-8"
    java:
      source: "11"
      target: "11"
```

|   |而不是硬编码这些值，你也可以[在构建时展开信息属性](howto.html#howto.properties-and-configuration.expand-properties)。<br/><br/>假设你使用 Maven，你可以将前面的示例重写如下：<br/><br/>属性<br/><br/><br/>593<582">>>|
|---| |

#### 2.10.3.Git 提交信息

`info`端点的另一个有用特性是，它能够在构建项目时发布有关你的`git`源代码库状态的信息。如果`Git属性` Bean 是可用的，则可以使用`info`端点来公开这些属性。

|   |如果`git.properties`文件在 Classpath 的根目录下可用，则`Git属性` Bean 是自动配置的。<br/>有关更多详细信息，请参见“[如何生成 Git 信息](howto.html#howto.build.generate-git-info)”。|
|---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

默认情况下，端点公开`git.branch`、`git.commit.id`和`git.commit.time`属性（如果存在的话）。如果不希望在端点响应中包含任何这些属性，则需要将它们从`git.properties`文件中排除。如果要显示完整的 Git 信息（即`git.properties`的完整内容），请使用`management.info.git.mode`属性，如下所示：

属性

```
management.info.git.mode=full
```

Yaml

```
management:
  info:
    git:
      mode: "full"
```

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

属性

```
management.info.git.enabled=false
```

Yaml

```
management:
  info:
    git:
      enabled: false
```

#### 2.10.4.建立信息

如果`Build属性` Bean 是可用的，那么`info`端点也可以发布有关你的构建的信息。如果`META-INF/build-info.properties`文件在 Classpath 中可用，就会发生这种情况。

|   |Maven 和 Gradle 插件都可以生成该文件。<br/>有关更多详细信息，请参见“[如何生成构建信息](howto.html#howto.build.generate-info)”。|
|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------|

#### 2.10.5.Java 信息

`info`端点发布有关你的 Java 运行时环境的信息，有关更多详细信息，请参见[`JavaInfo`]（https://DOCS. Spring.io/ Spring-boot/DOCS/2.6.4/api/org/springframework/boot/info/info/javainfo.html）。

#### 2.10.6.编写自定义信息贡献者

要提供自定义的应用程序信息，你可以注册实现[`InfoContributor`]（https://github.com/ Spring-projects/ Spring-boot/tree/v2.6.4/ Spring-boot-project/ Spring-boot-actuator/SRC/main/java/org/springframework/boot/actuate/actuate/info/info/infutor.java）接口的 Spring bean。

下面的示例以单个值贡献一个`example`条目：

```
import java.util.Collections;

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

@Component
public class MyInfoContributor implements InfoContributor {

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

}

```

如果你到达`info`端点，你应该会看到一个包含以下附加条目的响应：

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

## 3. 基于 HTTP 的监控和管理

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

|   |Spring MVC、 Spring WebFlux 和 Jersey 原生地支持致动器。如果 Jersey 和 Spring MVC 都可用，则使用 Spring MVC。|
|---|------------------------------------------------------------------------------------------------------------------------------------------------|

|   |Jackson 是一个必需的依赖项，以便获得 API 文档中记录的正确的 JSON 响应（[HTML](https://docs.spring.io/spring-boot/docs/2.6.4/actuator-api/htmlsingle)或[PDF](https://docs.spring.io/spring-boot/docs/2.6.4/actuator-api/pdf/spring-boot-actuator-web-api.pdf)）。|
|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

### 3.1.自定义管理端点路径 ###

有时，定制管理端点的前缀是有用的。例如，你的应用程序可能已经将`/actuator`用于其他目的。可以使用`management.endpoints.web.base-path`属性更改管理端点的前缀，如下例所示：

属性

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

Yaml

```
management:
  endpoints:
    web:
      base-path: "/manage"
```

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

|   |除非管理端口已被配置为[使用不同的 HTTP 端口公开端点](#actuator.monitoring.customizing-management-server-port)，否则`management.endpoints.web.base-path`相对于`server.servlet.context-path`（对于 Servlet Web 应用程序）或`spring.webflux.base-path`（对于反应性 Web 应用程序）。<br/>如果配置了`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
```

Yaml

```
management:
  endpoints:
    web:
      base-path: "/"
      path-mapping:
        health: "healthcheck"
```

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

对于基于云的部署，使用默认的 HTTP 端口公开管理端点是一个明智的选择。但是，如果你的应用程序在你自己的数据中心内运行，那么你可能更喜欢使用不同的 HTTP 端口来公开端点。

你可以设置`management.server.port`属性来更改 HTTP 端口，如下例所示：

属性

```
management.server.port=8081
```

Yaml

```
management:
  server:
    port: 8081
```

|   |在 Cloud Foundry 上，默认情况下，应用程序仅在端口 8080 上接收用于 HTTP 和 TCP 路由的请求。<br/>如果你想在 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
```

Yaml

```
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
```

Yaml

```
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`属性来定制管理端点可用的地址。如果你只想监听内部或面向 Ops 的网络，或者只监听`localhost`中的连接，那么这样做会很有用。

|   |只有当端口与主服务器端口不同时，你才可以在不同的地址上监听。|
|---|-------------------------------------------------------------------------------------------|

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

属性

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

Yaml

```
management:
  server:
    port: 8081
    address: "127.0.0.1"
```

### 3.5.禁用 HTTP 端点

如果不想在 HTTP 上公开端点，可以将管理端口设置为`-1`，如下例所示：

属性

```
management.server.port=-1
```

Yaml

```
management:
  server:
    port: -1
```

你也可以通过使用`management.endpoints.web.exposure.exclude`属性来实现这一点，如下例所示：

属性

```
management.endpoints.web.exposure.exclude=*
```

Yaml

```
management:
  endpoints:
    web:
      exposure:
        exclude: "*"
```

## 4. JMX 的监控与管理

Java 管理扩展提供了一种标准的机制来监视和管理应用程序。默认情况下，不启用此功能。你可以通过将`spring.jmx.enabled`配置属性设置为`true`来打开它。 Spring 引导将最合适的`MBeanServer`公开为具有`mbeanServer`的 ID 的 Bean。使用 Spring JMX 注释（`@ManagedResource`，`@ManagedAttribute`，或`@ManagedOperation`）进行注释的任何 bean 都会暴露给它。

如果你的平台提供了一个标准的`MBeanServer`， Spring boot 将使用它，并在必要时默认为 VM`MBeanServer`。如果所有这些都失败了，将创建一个新的`MBeanServer`。

参见[`JmxAutoConfiguration`]（https://github.com/ Spring-projects/ Spring-boot/tree/v2.6.4/ Spring-boot-project/ Spring-boot-autofigure/SRC/main/java/org/springframework/boot/autofigure/jmx/jmxautofconfiguration.java）类获取更多详细信息。

默认情况下， Spring 引导还将管理端点作为`org.springframework.boot`域下的 JMXMBeans 公开。要完全控制 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
```

Yaml

```
spring:
  jmx:
    unique-names: true
management:
  endpoints:
    jmx:
      domain: "com.example.myapp"
```

### 4.2.禁用 JMX 端点

如果不想在 JMX 上公开端点，可以将`management.endpoints.jmx.exposure.exclude`属性设置为`*`，如下例所示：

属性

```
management.endpoints.jmx.exposure.exclude=*
```

Yaml

```
management:
  endpoints:
    jmx:
      exposure:
        exclude: "*"
```

### 4.3.在 HTTP 上使用 Jolokia 进行 JMX

Jolokia 是一个 JMX-HTTP 桥，它提供了一种访问 JMX Bean 的替代方法。若要使用 Jolokia，请包含对`org.jolokia:jolokia-core`的依赖关系。例如，对于 Maven，你将添加以下依赖项：

```
<dependency>
    <groupId>org.jolokia</groupId>
    <artifactId>jolokia-core</artifactId>
</dependency>
```

然后，你可以通过向`management.endpoints.web.exposure.include`属性添加`jolokia`或`*`来公开 Jolokia 端点。然后，你可以使用管理 HTTP 服务器上的`/actuator/jolokia`访问它。

|   |Jolokia 端点将 Jolokia 的 Servlet 公开为执行器端点。<br/>结果，它是特定于 Servlet 环境的，例如 Spring MVC 和 Jersey。<br/>端点在 WebFlux 应用程序中是不可用的。|
|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

#### 4.3.1.定制 Jolokia

Jolokia 有许多设置，你通常会通过设置 Servlet 参数来配置这些设置。通过 Spring 引导，你可以使用你的`application.properties`文件。要这样做，请在参数前缀`management.endpoint.jolokia.config.`，如下例所示：

属性

```
management.endpoint.jolokia.config.debug=true
```

Yaml

```
management:
  endpoint:
    jolokia:
      config:
        debug: true
```

#### 4.3.2.禁用 Jolokia

如果你使用 Jolokia，但不希望 Spring 引导来配置它，请将`management.endpoint.jolokia.enabled`属性设置为`false`，如下所示：

属性

```
management.endpoint.jolokia.enabled=false
```

Yaml

```
management:
  endpoint:
    jolokia:
      enabled: false
```

## 5. 日志记录器

Spring 启动执行器包括在运行时查看和配置应用程序的日志级别的能力。你可以查看整个列表，也可以查看单个日志程序的配置，该配置由显式配置的日志级别以及日志框架赋予它的有效日志级别组成。这些级别可以是：

* `TRACE`

* `DEBUG`

* `INFO`

* `WARN`

* `ERROR`

* `FATAL`

* `OFF`

* `null`

`null`表示没有显式配置。

### 5.1.配置记录器

要配置给定的记录器，`POST`将一个部分实体配置到资源的 URI，如下例所示：

```
{
    "configuredLevel": "DEBUG"
}
```

|   |要“重置”记录器的特定级别（并使用默认配置），可以将值`null`传递为`configuredLevel`。|
|---|-------------------------------------------------------------------------------------------------------------------------------------------------|

## 6. 度量

Spring Boot Actuator 为[Micrometer](https://micrometer.io)提供依赖管理和自动配置，这是一种支持[众多的监测系统](https://micrometer.io/docs)的应用程序度量外观，包括：

* [AppOptics](#actuator.metrics.export.appoptics)

* [Atlas](#actuator.metrics.export.atlas)

* [Datadog](#actuator.metrics.export.datadog)

* [Dynatrace](#actuator.metrics.export.dynatrace)

* [Elastic](#actuator.metrics.export.elastic)

* [Ganglia](#actuator.metrics.export.ganglia)

* [Graphite](#actuator.metrics.export.graphite)

* [Humio](#actuator.metrics.export.humio)

* [Influx](#actuator.metrics.export.influx)

* [JMX](#actuator.metrics.export.jmx)

* [KairosDB](#actuator.metrics.export.kairos)

* [New Relic](#actuator.metrics.export.newrelic)

* [Prometheus](#actuator.metrics.export.prometheus)

* [SignalFx](#actuator.metrics.export.signalfx)

* [简单（内存中）](#actuator.metrics.export.simple)

* [Stackdriver](#actuator.metrics.export.stackdriver)

* [StatsD](#actuator.metrics.export.statsd)

* [Wavefront](#actuator.metrics.export.wavefront)

|   |要了解有关千分尺功能的更多信息，请参见其[参考文献](https://micrometer.io/docs)，特别是[概念部分](https://micrometer.io/docs/concepts)。|
|---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

### 6.1.开始

Spring 引导自动配置组合`MeterRegistry`，并为其在 Classpath 上找到的每个支持的实现向组合添加注册表。在运行时 Classpath 中对`micrometer-registry-{system}`具有依赖关系就足以使 Spring 引导配置注册表。

大多数注册中心都有共同的特征。例如，即使在 Classpath 上的微米表注册实现也可以禁用特定的注册中心。以下示例禁用 Datadog:

属性

```
management.metrics.export.datadog.enabled=false
```

Yaml

```
management:
  metrics:
    export:
      datadog:
        enabled: false
```

除非特定于注册中心的属性另有说明，否则你也可以禁用所有注册中心，如下例所示：

属性

```
management.metrics.export.defaults.enabled=false
```

Yaml

```
management:
  metrics:
    export:
      defaults:
        enabled: false
```

Spring Boot 还将任何自动配置的注册中心添加到`Metrics`类上的全局静态复合注册中心，除非你明确地告诉它不要：

属性

```
management.metrics.use-global-registry=false
```

Yaml

```
management:
  metrics:
    use-global-registry: false
```

你可以注册任意数量的`MeterRegistryCustomizer`bean，以进一步配置注册表，例如在向注册表注册任何米之前应用公共标记：

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

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

@Configuration(proxyBeanMethods = false)
public class MyMeterRegistryConfiguration {

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

}

```

你可以通过更具体地说明泛型类型来对特定的注册中心实现应用自定义：

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

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

@Configuration(proxyBeanMethods = false)
public class MyMeterRegistryConfiguration {

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

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

}

```

Spring 还可以启动[配置内置的仪表](#actuator.metrics.supported)，这可以通过配置或专用注释标记来控制。

### 6.2.支持的监测系统

这一节简要介绍了每个支持的监控系统。

#### 6.2.1.APPATICS

默认情况下，AppOptics 注册中心会定期将指标推到`[api.appoptics.com/v1/measurements](https://api.appoptics.com/v1/measurements)`。要将度量导出到 SaaS[AppOptics](https://micrometer.io/docs/registry/appOptics)，必须提供你的 API 令牌：

属性

```
management.metrics.export.appoptics.api-token=YOUR_TOKEN
```

Yaml

```
management:
  metrics:
    export:
      appoptics:
        api-token: "YOUR_TOKEN"
```

#### 6.2.2.阿特拉斯

默认情况下，指标导出到在本地机器上运行的[Atlas](https://micrometer.io/docs/registry/atlas)。你可以提供[Atlas 服务器](https://github.com/Netflix/atlas)的位置：

Properties

```
management.metrics.export.atlas.uri=https://atlas.example.com:7101/api/v1/publish
```

Yaml

```
management:
  metrics:
    export:
      atlas:
        uri: "https://atlas.example.com:7101/api/v1/publish"
```

#### 6.2.3.Datadog

Datadog 注册中心定期将指标推到[datadoghq](https://www.datadoghq.com)。要将指标导出到[Datadog](https://micrometer.io/docs/registry/datadog)，你必须提供你的 API 键：

Properties

```
management.metrics.export.datadog.api-key=YOUR_KEY
```

Yaml

```
management:
  metrics:
    export:
      datadog:
        api-key: "YOUR_KEY"
```

你还可以更改将指标发送到 Datadog 的时间间隔：

Properties

```
management.metrics.export.datadog.step=30s
```

Yaml

```
management:
  metrics:
    export:
      datadog:
        step: "30s"
```

#### 6.2.4.Dynatrace

Dynatrace 提供了两个吸收 API 的指标，这两个指标都是为[Micrometer](https://micrometer.io/docs/registry/dynatrace)实现的。`v1`命名空间中的配置属性仅在导出到[TimeSeries V1API](https://www.dynatrace.com/support/help/dynatrace-api/environment-api/metric-v1/)时才应用。`v2`名称空间中的配置属性仅在导出到[Metrics V2API](https://www.dynatrace.com/support/help/dynatrace-api/environment-api/metric-v2/post-ingest-metrics/)时才应用。注意，这种集成一次只能导出到 API 的`v1`或`v2`版本。如果`device-id`（v1 需要，但在 v2 中不使用）在`v1`命名空间中设置，则将指标导出到`v1`端点。否则，假定`v2`。

##### V2API

你可以通过两种方式使用 V2API。

如果本地 OneAgent 在主机上运行，则度量指标将自动导出到[本地一个代理摄取端点](https://www.dynatrace.com/support/help/how-to-use-dynatrace/metrics/metric-ingestion/ingestion-methods/local-api/)。摄取端点将指标转发到 Dynatrace 后端。这是默认的行为，除了依赖于`io.micrometer:micrometer-registry-dynatrace`之外，不需要特殊的设置。

如果没有运行本地 OneAgent，则需要[Metrics V2API](https://www.dynatrace.com/support/help/dynatrace-api/environment-api/metric-v2/post-ingest-metrics/)的端点和一个 API 令牌。[API token](https://www.dynatrace.com/support/help/dynatrace-api/basics/dynatrace-api-authentication/)必须具有“摄入指标”（`metrics.ingest`）权限集。我们建议将令牌的范围限制为这个权限。你必须确保端点 URI 包含以下路径（例如，`/api/v2/metrics/ingest`）：

根据你的部署选项，Metrics API v2Ingest 端点的 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 配置指标导出：

Properties

```
management.metrics.export.dynatrace.uri=https://example.live.dynatrace.com/api/v2/metrics/ingest
management.metrics.export.dynatrace.api-token=YOUR_TOKEN
```

Yaml

```
management:
  metrics:
    export:
      dynatrace:
        uri: "https://example.live.dynatrace.com/api/v2/metrics/ingest"
        api-token: "YOUR_TOKEN"
```

在使用 Dynatrace V2API 时，可以使用以下可选特性：

* 公制密钥前缀：设置一个前缀，该前缀用于所有导出的公制密钥。

* 丰富 Dynatrace 元数据：如果正在运行一个 Agent 或 Dynatrace 操作符，则使用额外的元数据（例如，关于主机、进程或 POD）丰富度量。

* 默认维度：指定添加到所有导出度量中的键-值对。如果使用 Micrometer 指定了具有相同键值的标记，则它们会覆盖默认的尺寸。

可以不指定 URI 和 API 令牌，如下面的示例所示。在此场景中，使用本地 OneAgent 端点：

Properties

```
management.metrics.export.dynatrace.v2.metric-key-prefix=your.key.prefix
management.metrics.export.dynatrace.v2.enrich-with-dynatrace-metadata=true
management.metrics.export.dynatrace.v2.default-dimensions.key1=value1
management.metrics.export.dynatrace.v2.default-dimensions.key2=value2
```

Yaml

```
management:
  metrics:
    export:
      dynatrace:
        # 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"
```

##### V1API（旧版）

Dynatrace V1API metrics 注册中心通过使用[TimeSeries V1API](https://www.dynatrace.com/support/help/dynatrace-api/environment-api/metric-v1/)定期将指标推送到配置的 URI。对于与现有设置的向后兼容性，当设置`device-id`时（对于 V1 是必需的，但在 V2 中不使用），度量值将导出到 TimeSeries V1 端点。要将指标导出到[Dynatrace](https://micrometer.io/docs/registry/dynatrace)，必须提供你的 API 令牌、设备 ID 和 URI:

属性

```
management.metrics.export.dynatrace.uri=https://{your-environment-id}.live.dynatrace.com
management.metrics.export.dynatrace.api-token=YOUR_TOKEN
management.metrics.export.dynatrace.v1.device-id=YOUR_DEVICE_ID
```

Yaml

```
management:
  metrics:
    export:
      dynatrace:
        uri: "https://{your-environment-id}.live.dynatrace.com"
        api-token: "YOUR_TOKEN"
        v1:
          device-id: "YOUR_DEVICE_ID"
```

对于 V1API，你必须指定没有路径的基本环境 URI，因为 V1 端点路径是自动添加的。

##### 与版本无关的设置

除了 API 端点和令牌，你还可以更改将指标发送到 Dynatrace 的时间间隔。默认的导出间隔是`60s`。以下示例将导出间隔设置为 30 秒：

属性

```
management.metrics.export.dynatrace.step=30s
```

Yaml

```
management:
  metrics:
    export:
      dynatrace:
        step: "30s"
```

你可以在[千分尺文档](https://micrometer.io/docs/registry/dynatrace)中找到有关如何为千分尺设置 Dynatrace Exporter 的更多信息。

#### 6.2.5.弹性

默认情况下，指标导出到在本地机器上运行的[Elastic](https://micrometer.io/docs/registry/elastic)。你可以使用以下属性提供要使用的 Elastic 服务器的位置：

属性

```
management.metrics.export.elastic.host=https://elastic.example.com:8086
```

Yaml

```
management:
  metrics:
    export:
      elastic:
        host: "https://elastic.example.com:8086"
```

#### 6.2.6.神经节

默认情况下，指标导出到在本地机器上运行的[Ganglia](https://micrometer.io/docs/registry/ganglia)。你可以提供[Ganglia 服务器](http://ganglia.sourceforge.net)主机和端口，如下例所示：

属性

```
management.metrics.export.ganglia.host=ganglia.example.com
management.metrics.export.ganglia.port=9649
```

Yaml

```
management:
  metrics:
    export:
      ganglia:
        host: "ganglia.example.com"
        port: 9649
```

#### 6.2.7.石墨

默认情况下，指标导出到在本地机器上运行的[Graphite](https://micrometer.io/docs/registry/graphite)。你可以提供[石墨服务器](https://graphiteapp.org)主机和端口，如下例所示：

属性

```
management.metrics.export.graphite.host=graphite.example.com
management.metrics.export.graphite.port=9004
```

Yaml

```
management:
  metrics:
     export:
       graphite:
         host: "graphite.example.com"
         port: 9004
```

Micrometer 提供了一个默认的`HierarchicalNameMapper`，它控制一个维度表 ID 是[映射到平面层次结构名称](https://micrometer.io/docs/registry/graphite#_hierarchical_name_mapping)的方式。

|   |要控制此行为，请定义你的`GraphiteMeterRegistry`并提供你自己的`HierarchicalNameMapper`。<br/>提供自动配置的`GraphiteConfig`和`Clock`bean，除非你定义自己的：<br/><br/>|
|---| |

#### 6.2.8.Humio

默认情况下，Humio 注册中心会定期将指标推到[cloud.humio.com](https://cloud.humio.com)。要将指标导出到 SaaS[Humio](https://micrometer.io/docs/registry/humio)，你必须提供你的 API 令牌：

属性

```
management.metrics.export.humio.api-token=YOUR_TOKEN
```

Yaml

```
management:
  metrics:
    export:
      humio:
        api-token: "YOUR_TOKEN"
```

你还应该配置一个或多个标记，以标识将指标推送到的数据源：

属性

```
management.metrics.export.humio.tags.alpha=a
management.metrics.export.humio.tags.bravo=b
```

Yaml

```
management:
  metrics:
    export:
      humio:
        tags:
          alpha: "a"
          bravo: "b"
```

#### 6.2.9.涌入

默认情况下，指标将导出到使用默认配置在本地计算机上运行的[Influx](https://micrometer.io/docs/registry/influx)V1 实例。要将指标导出到 InfluxDB V2，请配置`org`、`bucket`以及用于编写指标的身份验证`token`。你可以通过以下方式提供要使用的[influg 服务器](https://www.influxdata.com)的位置：

属性

```
management.metrics.export.influx.uri=https://influx.example.com:8086
```

Yaml

```
management:
  metrics:
    export:
      influx:
        uri: "https://influx.example.com:8086"
```

#### 6.2.10.JMX

Micrometer 提供了到[JMX](https://micrometer.io/docs/registry/jmx)的层次映射，主要是作为一种本地查看度量的廉价且便携的方式。默认情况下，指标导出到`metrics`JMX 域。你可以通过以下方式提供要使用的域：

属性

```
management.metrics.export.jmx.domain=com.example.app.metrics
```

Yaml

```
management:
  metrics:
    export:
      jmx:
        domain: "com.example.app.metrics"
```

Micrometer 提供了一个默认的`HierarchicalNameMapper`，它控制一个维度表 ID 是[映射到平面层次结构名称](https://micrometer.io/docs/registry/jmx#_hierarchical_name_mapping)的方式。

|   |要控制此行为，请定义你的`JmxMeterRegistry`并提供你自己的`HierarchicalNameMapper`。<br/>提供自动配置的`JmxConfig`和`Clock`bean，除非你自己定义：<br/><br/>|
|---| |

#### 6.2.11.KairosDB

默认情况下，指标导出到在本地机器上运行的[KairosDB](https://micrometer.io/docs/registry/kairos)。你可以通过以下方式提供要使用的[KaiRosDB 服务器](https://kairosdb.github.io/)的位置：

属性

```
management.metrics.export.kairos.uri=https://kairosdb.example.com:8080/api/v1/datapoints
```

Yaml

```
management:
  metrics:
    export:
      kairos:
        uri: "https://kairosdb.example.com:8080/api/v1/datapoints"
```

#### 6.2.12.新遗迹

一个新的 Relic 注册中心定期将指标推到[New Relic](https://micrometer.io/docs/registry/new-relic)。要将指标导出到[New Relic](https://newrelic.com)，你必须提供你的 API 密钥和帐户 ID:

属性

```
management.metrics.export.newrelic.api-key=YOUR_KEY
management.metrics.export.newrelic.account-id=YOUR_ACCOUNT_ID
```

Yaml

```
management:
  metrics:
    export:
      newrelic:
        api-key: "YOUR_KEY"
        account-id: "YOUR_ACCOUNT_ID"
```

你还可以更改将指标发送到 New Relic 的时间间隔：

属性

```
management.metrics.export.newrelic.step=30s
```

Yaml

```
management:
  metrics:
    export:
      newrelic:
        step: "30s"
```

默认情况下，度量是通过 REST 调用发布的，但是如果你在 Classpath 上有 Java Agent API，那么你也可以使用它：

属性

```
management.metrics.export.newrelic.client-provider-type=insights-agent
```

Yaml

```
management:
  metrics:
    export:
      newrelic:
        client-provider-type: "insights-agent"
```

最后，你可以通过定义自己的`NewRelicClientProvider` Bean 来获得完全控制。

#### 6.2.13.Prometheus

[Prometheus](https://micrometer.io/docs/registry/prometheus)期望抓取或轮询单个应用程序实例以获取指标。 Spring 引导在`/actuator/prometheus`处提供执行器端点，以呈现具有适当格式的[普罗米修斯刮](https://prometheus.io)。

|   |默认情况下，端点不可用，必须公开。有关更多详细信息，请参见[公开端点](#actuator.endpoints.exposing)。|
|---|---------------------------------------------------------------------------------------------------------------------------------------|

下面的示例`scrape_config`将添加到`prometheus.yml`:

```
scrape_configs:
  - job_name: "spring"
    metrics_path: "/actuator/prometheus"
    static_configs:
      - targets: ["HOST:PORT"]
```

对于可能存在的时间不够长而无法被抓取的临时或批处理作业，可以使用[普罗米修斯 · 普什盖特](https://github.com/prometheus/pushgateway)支持将度量公开给普罗米修斯。要启用 Prometheus PushGateway 支持，请在项目中添加以下依赖项：

```
<dependency>
    <groupId>io.prometheus</groupId>
    <artifactId>simpleclient_pushgateway</artifactId>
</dependency>
```

当 Classpath 上存在 Prometheus PushGateway 依赖项并且`management.metrics.export.prometheus.pushgateway.enabled`属性设置为`true`时，将自动配置`PrometheusPushGatewayManager` Bean。这管理了将指标推送到 Prometheus PushGateway 的过程。

你可以使用`management.metrics.export.prometheus.pushgateway`下的属性来调优`PrometheusPushGatewayManager`。对于高级配置，还可以提供自己的`PrometheusPushGatewayManager` Bean。

#### 6.2.14.SignalFX

SignalFX Registry 定期将指标推到[SignalFx](https://micrometer.io/docs/registry/signalFx)。要将指标导出到[SignalFx](https://www.signalfx.com)，你必须提供访问令牌：

属性

```
management.metrics.export.signalfx.access-token=YOUR_ACCESS_TOKEN
```

Yaml

```
management:
  metrics:
    export:
      signalfx:
        access-token: "YOUR_ACCESS_TOKEN"
```

你还可以更改将指标发送到 SignalFX 的间隔时间：

属性

```
management.metrics.export.signalfx.step=30s
```

Yaml

```
management:
  metrics:
    export:
      signalfx:
        step: "30s"
```

#### 6.2.15.简单

Micrometer 附带了一个简单的内存后端，如果没有配置其他注册中心，该后端将自动用作后备。这让你看到在[指标端点](#actuator.metrics.endpoint)中收集了哪些指标。

一旦你使用任何其他可用的后端，内存中的后端就会禁用它自己。你还可以显式地禁用它：

属性

```
management.metrics.export.simple.enabled=false
```

Yaml

```
management:
  metrics:
    export:
      simple:
        enabled: false
```

#### 6.2.16.Stackdriver

StackDriver 注册表定期将指标推到[Stackdriver](https://cloud.google.com/stackdriver/)。要将指标导出到 SaaS[Stackdriver](https://micrometer.io/docs/registry/stackdriver)，你必须提供你的 Google Cloud 项目 ID:

属性

```
management.metrics.export.stackdriver.project-id=my-project
```

Yaml

```
management:
  metrics:
    export:
      stackdriver:
        project-id: "my-project"
```

你还可以更改将指标发送到 StackDriver 的间隔时间：

属性

```
management.metrics.export.stackdriver.step=30s
```

Yaml

```
management:
  metrics:
    export:
      stackdriver:
        step: "30s"
```

#### 6.2.17.统计 d

STATSD 注册中心急切地将 UDP 上的指标推送到 STATSD 代理。默认情况下，指标被导出到在本地机器上运行的[StatsD](https://micrometer.io/docs/registry/statsD)代理。你可以使用以下方法提供要使用的 STATSD 代理主机、端口和协议：

属性

```
management.metrics.export.statsd.host=statsd.example.com
management.metrics.export.statsd.port=9125
management.metrics.export.statsd.protocol=udp
```

Yaml

```
management:
  metrics:
    export:
      statsd:
        host: "statsd.example.com"
        port: 9125
        protocol: "udp"
```

你也可以将 STATSD 行协议更改为使用（默认为 Datadog）：

属性

```
management.metrics.export.statsd.flavor=etsy
```

Yaml

```
management:
  metrics:
    export:
      statsd:
        flavor: "etsy"
```

#### 6.2.18.波阵面

Wavefront 注册中心定期将指标推到[Wavefront](https://micrometer.io/docs/registry/wavefront)。如果要直接将指标导出到[Wavefront](https://www.wavefront.com/)，则必须提供你的 API 令牌：

属性

```
management.metrics.export.wavefront.api-token=YOUR_API_TOKEN
```

Yaml

```
management:
  metrics:
    export:
      wavefront:
        api-token: "YOUR_API_TOKEN"
```

或者，你可以在你的环境中使用 Wavefront 侧车或内部代理将度量数据转发到 Wavefront API 主机：

属性

```
management.metrics.export.wavefront.uri=proxy://localhost:2878
```

Yaml

```
management:
  metrics:
    export:
      wavefront:
        uri: "proxy://localhost:2878"
```

|   |如果将指标发布到 Wavefront 代理（如[Wavefront 文档](https://docs.wavefront.com/proxies_installing.html)中所述），则主机必须为`proxy://HOST:PORT`格式。|
|---|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

你还可以更改将指标发送到 Wavefront 的间隔时间：

属性

```
management.metrics.export.wavefront.step=30s
```

Yaml

```
management:
  metrics:
    export:
      wavefront:
        step: "30s"
```

### 6.3.支持的度量和计量器

Spring Boot 为各种各样的技术提供了自动仪表注册。在大多数情况下，默认值提供了可以发布到任何受支持的监视系统的合理指标。

#### 6.3.1.JVM 度量

自动配置通过使用核心 Micrometer 类来实现 JVM 度量。JVM 度量以`jvm.`度量名称发布。

提供了以下 JVM 指标：

* 各种内存和缓冲池详细信息

* 与垃圾收集相关的统计信息

* 线程利用率

* 加载和卸载的类的数量

#### 6.3.2.系统度量

自动配置通过使用核心微米表类来实现系统度量。系统度量在`system.`、`process.`和`disk.`米表名称下发布。

提供了以下系统指标：

* CPU 度量

* 文件描述符度量

* 正常运行时间指标（应用程序运行的时间和绝对启动时间的固定指标）

* 可用磁盘空间

#### 6.3.3.应用程序启动度量

自动配置公开应用程序启动时间指标：

* `application.started.time`:启动应用程序所需的时间。

* `application.ready.time`:应用程序准备好服务请求所需的时间。

度量由应用程序类的完全限定名称标记。

#### 6.3.4.记录器指标

自动配置可以为 logback 和 log4j2 启用事件度量。详细信息在`log4j2.events.`或`logback.events.`表名称下发布。

#### 6.3.5.任务执行和调度指标

自动配置允许对所有可用的`ThreadPoolTaskExecutor`和`ThreadPoolTaskScheduler`bean 进行插装，只要下面的`ThreadPoolExecutor`可用。度量由执行器的名称标记，该名称来自 Bean 名称。

#### 6.3.6. Spring MVC 度量

自动配置使所有由 Spring MVC 控制器和功能处理程序处理的请求的检测成为可能。默认情况下，度量值是用名称`http.server.requests`生成的。你可以通过设置`management.metrics.web.server.request.metric-name`属性来定制名称。

`@Timed`批注在`@Controller`类和`@RequestMapping`方法上都是支持的（详见[@ 定时注释支持](#actuator.metrics.supported.timed-annotation)）。如果不想记录所有 Spring MVC 请求的度量，则可以将`management.metrics.web.server.request.autotime.enabled`设置为`false`，并专门使用`@Timed`注释。

默认情况下， Spring MVC 相关度量标记有以下信息：

|    Tag    |说明|
|-----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|`exception`|处理请求时引发的任何异常的简单类名。|
| `method`  |请求的方法（例如，`GET`或`POST`）|
| `outcome` |请求的结果，基于响应的状态代码。<br/>1xx 是`INFORMATIONAL`，2xx 是`SUCCESS`，3xx 是`REDIRECTION`，4xx 是`CLIENT_ERROR`，5xx 是`SERVER_ERROR`|
| `status`  |响应的 HTTP 状态代码（例如，`200`或`500`）|
|   `uri`   |如果可能的话，在变量替换之前提供请求的 URI 模板（例如，`/api/person/{id}`）|

要添加到默认标记中，请提供一个或多个实现`@Bean`的`WebMvcTagsContributor`s。要替换默认标记，请提供一个实现`WebMvcTagsProvider`的`@Bean`。

|   |在某些情况下，在 Web 控制器中处理的异常不被记录为请求度量标记。<br/>应用程序可以通过[将已处理的异常设置为请求属性](web.html#web.servlet.spring-mvc.error-handling)OPT 并记录异常。|
|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

#### 6.3.7. Spring WebFlux 度量

自动配置允许检测由 Spring WebFlux 控制器和功能处理程序处理的所有请求。默认情况下，度量值以`http.server.requests`的名称生成。你可以通过设置`management.metrics.web.server.request.metric-name`属性来定制名称。

`@Timed`批注在`@Controller`类和`@RequestMapping`方法上都是支持的（详见[@ 定时注释支持](#actuator.metrics.supported.timed-annotation)）。如果不想记录所有 Spring WebFlux 请求的度量，则可以将`management.metrics.web.server.request.autotime.enabled`设置为`false`，并专门使用`@Timed`注释。

默认情况下，WebFlux 相关度量标记有以下信息：

|    Tag    |说明|
|-----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|`exception`|处理请求时引发的任何异常的简单类名。|
| `method`  |请求的方法（例如，`GET`或`POST`）|
| `outcome` |请求的结果，基于响应的状态代码。<br/>1xx 是`INFORMATIONAL`，2xx 是`SUCCESS`，3xx 是`REDIRECTION`，4xx 是`CLIENT_ERROR`，5xx 是`SERVER_ERROR`|
| `status`  |响应的 HTTP 状态代码（例如，`200`或`500`）|
|   `uri`   |如果可能的话，在变量替换之前提供请求的 URI 模板（例如，`/api/person/{id}`）|

要添加到默认标记中，请提供一个或多个实现`WebFluxTagsContributor`的 bean。要替换默认标记，请提供实现`WebFluxTagsProvider`的 Bean。

|   |在某些情况下，在控制器和处理程序函数中处理的异常不被记录为请求度量标记。<br/>应用程序可以通过[将已处理的异常设置为请求属性](web.html#web.reactive.webflux.error-handling)OPT 和记录异常。|
|---|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

#### 6.3.8.泽西服务器指标

自动配置支持对 Jersey JAX-RS 实现处理的所有请求进行检测。默认情况下，度量值是用名称`http.server.requests`生成的。你可以通过设置`management.metrics.web.server.request.metric-name`属性来定制名称。

`@Timed`在请求处理类和方法上支持注释（有关详细信息，请参见[@ 定时注释支持](#actuator.metrics.supported.timed-annotation)）。如果不想记录所有 Jersey 请求的度量，可以将`management.metrics.web.server.request.autotime.enabled`设置为`false`，并专门使用`@Timed`注释。

默认情况下，Jersey Server Metrics 使用以下信息进行标记：

|    Tag    |说明|
|-----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|`exception`|处理请求时引发的任何异常的简单类名。|
| `method`  |请求的方法（例如，`GET`或`POST`）|
| `outcome` |请求的结果，基于响应的状态代码。<br/>1xx 是`INFORMATIONAL`，2xx 是`SUCCESS`，3xx 是`REDIRECTION`，4xx 是`CLIENT_ERROR`，5xx 是`SERVER_ERROR`|
| `status`  |响应的 HTTP 状态代码（例如，`200`或`500`）|
|   `uri`   |如果可能的话，在变量替换之前提供请求的 URI 模板（例如，`/api/person/{id}`）|

要定制标记，请提供实现`JerseyTagsProvider`的`@Bean`。

#### 6.3.9.HTTP 客户端度量

Spring 引导执行器管理`RestTemplate`和`WebClient`两者的仪表。为此，你必须插入自动配置的生成器，并使用它创建实例：

* `RestTemplateBuilder`表示`RestTemplate`

* `WebClient.Builder`表示`WebClient`

你还可以手动应用负责此检测的定制程序，即`MetricsRestTemplateCustomizer`和`MetricsWebClientCustomizer`。

默认情况下，度量值以`http.client.requests`的名称生成。你可以通过设置`management.metrics.web.client.request.metric-name`属性来定制名称。

默认情况下，由检测过的客户机生成的度量值被标记为以下信息：

|    Tag     |说明|
|------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|`clientName`|URI 的主机部分|
|  `method`  |请求的方法（例如，`GET`或`POST`）|
| `outcome`  |请求的结果，基于响应的状态代码。<br/>1xx 是`INFORMATIONAL`，2xx 是`SUCCESS`，3xx 是`REDIRECTION`，4xx 是`CLIENT_ERROR`，5xx 是`SERVER_ERROR`。否则，它是`UNKNOWN`。|
|  `status`  |响应的 HTTP 状态代码（如果可用的话）（例如，`200`或`500`）或`IO_ERROR`在 I/O 问题的情况下。否则，它是`CLIENT_ERROR`。|
|   `uri`    |如果可能的话，在变量替换之前提供请求的 URI 模板（例如，`/api/person/{id}`）|

为了自定义标记，并且根据你对客户机的选择，你可以提供一个`@Bean`来实现`RestTemplateExchangeTagsProvider`或`WebClientExchangeTagsProvider`。在`RestTemplateExchangeTags`和`WebClientExchangeTags`中有方便的静态函数。

#### 6.3.10. Tomcat 指标

自动配置仅在启用`MBeanRegistry`时才启用 Tomcat 的插装。默认情况下，`MBeanRegistry`是禁用的，但是你可以通过将`server.tomcat.mbeanregistry.enabled`设置为`true`来启用它。

Tomcat 度量在`tomcat.`度量名称下发布。

#### 6.3.11.缓存度量

自动配置允许在启动时检测所有可用的`Cache`实例，其度量值前缀为`cache`。缓存检测是针对一组基本的度量标准进行标准化的。另外，特定于缓存的指标也是可用的。

支持以下缓存库：

* 咖啡因

* Ehcache2

* 黑泽尔卡斯特

* 任何兼容的 JCache（JSR-107）实现

* 雷迪斯

度量由缓存的名称和`CacheManager`的名称标记，该名称来自 Bean 名称。

|   |只有在启动时配置的缓存才绑定到注册表。<br/>对于在缓存配置中未定义的缓存，例如在运行中创建的缓存或在启动阶段之后以编程方式创建的缓存，需要显式的注册。<br/>提供了`CacheMetricsRegistrar` Bean 以使该过程更容易。|
|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

#### 6.3.12.数据源度量

自动配置允许对所有可用的`DataSource`对象进行插装，这些对象的度量前缀为`jdbc.connections`。数据源插装产生的量规表示池中当前活动的、空闲的、最大允许的和最小允许的连接。

度量指标还由基于 Bean 名称计算的`DataSource`的名称标记。

|   |默认情况下， Spring boot 为所有受支持的数据源提供元数据。<br/>如果不支持你喜欢的数据源，你可以添加额外的`DataSourcePoolMetadataProvider`bean。<br/>参见`DataSourcePoolMetadataProvidersConfiguration`示例。|
|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

此外，特定于光的度量以`hikaricp`前缀公开。每个度量都由池的名称标记（你可以使用`spring.datasource.name`对其进行控制）。

#### 6.3.13. Hibernate 指标

如果`org.hibernate:hibernate-micrometer`在 Classpath 上，则所有启用了统计信息的 Hibernate `EntityManagerFactory`实例都将使用一个名为`hibernate`的度量指标进行检测。

度量还由`EntityManagerFactory`的名称标记，该名称来自 Bean 名称。

要启用统计信息，标准 JPA 属性`hibernate.generate_statistics`必须设置为`true`。你可以在自动配置的`EntityManagerFactory`上启用该功能：

属性

```
spring.jpa.properties[hibernate.generate_statistics]=true
```

Yaml

```
spring:
  jpa:
    properties:
      "[hibernate.generate_statistics]": true
```

#### 6.3.14. Spring 数据存储库指标

自动配置使所有 Spring 数据`Repository`方法调用的检测成为可能。默认情况下，度量值以`spring.data.repository.invocations`的名称生成。你可以通过设置`management.metrics.data.repository.metric-name`属性来定制名称。

`Repository`在`Repository`类和方法上支持`EntityManagerFactory`注释（有关详细信息，请参见[@ 定时注释支持](#actuator.metrics.supported.timed-annotation)）。如果不想记录所有`Repository`调用的度量，则可以将`management.metrics.data.repository.autotime.enabled`设置为`false`，并专门使用`@Timed`注释。

默认情况下，存储库调用相关的度量被标记为以下信息：

|    Tag     |说明|
|------------|---------------------------------------------------------------------------|
|`repository`|源的简单类名`Repository`。|
|  `method`  |调用的`Repository`方法的名称。|
|  `state`   |结果状态（`SUCCESS`，`ERROR`，`CANCELED`，或`RUNNING`）。|
|`exception` |从调用中抛出的任何异常的简单类名。|

要替换默认标记，请提供一个实现`RepositoryTagsProvider`的`@Bean`。

#### 6.3.15.RabbitMQ 度量

自动配置允许使用名为`rabbitmq`的度量来检测所有可用的 RabbitMQ 连接工厂。

#### 6.3.16. Spring 集成度量

Spring 只要`MeterRegistry` Bean 可用，集成就会自动提供[千分尺支持](https://docs.spring.io/spring-integration/docs/5.5.9/reference/html/system-management.html#micrometer-integration)。度量以`spring.integration.`度量名称发布。

#### 6.3.17.卡夫卡指标

自动配置寄存器`MicrometerConsumerListener`和`MicrometerProducerListener`分别用于自动配置的消费者工厂和生产者工厂。它还将`KafkaStreamsMicrometerListener`注册为`StreamsBuilderFactoryBean`。有关更多详细信息，请参见 Spring Kafka 文档的[千分尺本机度量](https://docs.spring.io/spring-kafka/docs/2.8.3/reference/html/#micrometer-native)部分。

#### 6.3.18.MongoDB 度量

本节简要介绍 MongoDB 的可用度量。

##### MongoDB 命令度量

自动配置寄存器`MongoMetricsCommandListener`与自动配置的`MongoClient`。

为发出给底层 MongoDB 驱动程序的每个命令创建一个名为`mongodb.driver.commands`的计时器度量。默认情况下，每个度量标准都带有以下信息：

|      Tag       |说明|
|----------------|------------------------------------------------------------|
|   `command`    |发出的命令的名称。|
|  `cluster.id`  |将命令发送到的集群的标识符。|
|`server.address`|该命令被发送到的服务器的地址。|
|    `status`    |命令的结果（`SUCCESS`或`FAILED`）。|

要替换默认的度量标记，请定义`MongoCommandTagsProvider` Bean，如下例所示：

```
import io.micrometer.core.instrument.binder.mongodb.MongoCommandTagsProvider;

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

@Configuration(proxyBeanMethods = false)
public class MyCommandTagsProviderConfiguration {

    @Bean
    public MongoCommandTagsProvider customCommandTagsProvider() {
        return new CustomCommandTagsProvider();
    }

}

```

要禁用自动配置的命令度量，请设置以下属性：

属性

```
management.metrics.mongo.command.enabled=false
```

Yaml

```
management:
  metrics:
    mongo:
      command:
        enabled: false
```

##### MongoDB 连接池指标

自动配置寄存器`MongoMetricsConnectionPoolListener`与自动配置的`MongoClient`。

为连接池创建了以下度量指标：

* `mongodb.driver.pool.size`报告连接池的当前大小，包括空闲成员和正在使用的成员。

* `mongodb.driver.pool.checkedout`报告当前使用的连接数。

* `mongodb.driver.pool.waitqueuesize`报告池中连接的等待队列的当前大小。

默认情况下，每个度量标准都带有以下信息：

|      Tag       |说明|
|----------------|-----------------------------------------------------------------------|
|  `cluster.id`  |连接池对应的群集的标识符。|
|`server.address`|连接池对应的服务器的地址。|

要替换默认的度量标记，请定义`MongoConnectionPoolTagsProvider` Bean:

```
import io.micrometer.core.instrument.binder.mongodb.MongoConnectionPoolTagsProvider;

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

@Configuration(proxyBeanMethods = false)
public class MyConnectionPoolTagsProviderConfiguration {

    @Bean
    public MongoConnectionPoolTagsProvider customConnectionPoolTagsProvider() {
        return new CustomConnectionPoolTagsProvider();
    }

}

```

要禁用自动配置的连接池指标，请设置以下属性：

属性

```
management.metrics.mongo.connectionpool.enabled=false
```

Yaml

```
management:
  metrics:
    mongo:
      connectionpool:
        enabled: false
```

#### 6.3.19. Jetty 指标

通过使用 Micrometer 的`JettyServerThreadPoolMetrics`，自动配置绑定了 Jetty 的`ThreadPool`的度量。 Jetty 的`Connector`实例的指标通过使用千分尺的`JettyConnectionMetrics`绑定，并且，当`server.ssl.enabled`设置为`true`时，千分尺的`JettySslHandshakeMetrics`。

#### 6.3.20.@ 定时注释支持

你可以使用`@Timed`包中的`io.micrometer.core.annotation`注释以及前面描述的几种受支持的技术。如果支持，可以在类级别或方法级别使用注释。

例如，下面的代码显示了如何使用注释来检验`@RestController`中的所有请求映射：

```
import java.util.List;

import io.micrometer.core.annotation.Timed;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@Timed
public class MyController {

    @GetMapping("/api/addresses")
    public List<Address> listAddress() {
        return ...
    }

    @GetMapping("/api/people")
    public List<Person> listPeople() {
        return ...
    }

}

```

如果你只想使用一个映射，那么可以使用方法上的注释，而不是类：

```
import java.util.List;

import io.micrometer.core.annotation.Timed;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyController {

    @GetMapping("/api/addresses")
    public List<Address> listAddress() {
        return ...
    }

    @GetMapping("/api/people")
    @Timed
    public List<Person> listPeople() {
        return ...
    }

}

```

如果你想更改特定方法的时间细节，还可以合并类级和方法级注释：

```
import java.util.List;

import io.micrometer.core.annotation.Timed;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@Timed
public class MyController {

    @GetMapping("/api/addresses")
    public List<Address> listAddress() {
        return ...
    }

    @GetMapping("/api/people")
    @Timed(extraTags = { "region", "us-east-1" })
    @Timed(value = "all.people", longTask = true)
    public List<Person> listPeople() {
        return ...
    }

}

```

|   |带有`@Timed`注释的`longTask = true`将为该方法启用一个长任务计时器。长任务计时器需要一个单独的度量名称，并且可以堆叠一个短任务计时器。|
|---|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

#### 6.3.21.Redis 度量

自动配置寄存器`MicrometerCommandLatencyRecorder`用于自动配置的`LettuceConnectionFactory`。有关更多详细信息，请参见生菜文档的[千分尺计量部分](https://lettuce.io/core/6.1.6.RELEASE/reference/index.html#command.latency.metrics.micrometer)。

### 6.4.注册自定义度量

要注册自定义度量，请将`MeterRegistry`插入到组件中：

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

import org.springframework.stereotype.Component;

@Component
public class MyBean {

    private final Dictionary dictionary;

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

}

```

如果你的指标依赖于其他 bean，我们建议你使用`MeterBinder`来注册它们：

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

import org.springframework.context.annotation.Bean;

public class MyMeterBinderConfiguration {

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

}

```

使用`MeterBinder`可以确保设置了正确的依赖关系，并且在检索到度量值时 Bean 是可用的。如果你发现你在组件或应用程序之间反复测试一套度量标准，那么`MeterBinder`实现也会很有用。

|   |默认情况下，来自所有`MeterBinder`bean 的指标都会自动绑定到 Spring 管理的`MeterRegistry`。|
|---|---------------------------------------------------------------------------------------------------------------|

### 6.5.自定义单个指标

如果需要对特定的`Meter`实例应用自定义，则可以使用`io.micrometer.core.instrument.config.MeterFilter`接口。

例如，如果你想将`mytag.region`标记重命名为`mytag.area`，用于所有以`com.example`开头的仪表 ID，那么你可以执行以下操作：

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

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

@Configuration(proxyBeanMethods = false)
public class MyMetricsFilterConfiguration {

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

}

```

|   |默认情况下，所有`MeterFilter`bean 都自动绑定到 Spring-managed`MeterRegistry`。<br/>确保通过使用 Spring-managed 的`MeterRegistry`来注册你的度量，而不是使用`Metrics`上的任何静态方法。<br/>这些方法使用不是 Spring-managed 的全局注册中心。|
|---|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

#### 6.5.1.公共标签

常见的标记通常用于对操作环境（如主机、实例、区域、堆栈等）进行维度下钻。Commons 标记应用于所有仪表，并且可以进行配置，如下例所示：

属性

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

Yaml

```
management:
  metrics:
    tags:
      region: "us-east-1"
      stack: "prod"
```

前面的示例将`region`和`stack`标记分别添加到所有值为`us-east-1`和`prod`的仪表上。

|   |如果使用 Graphite，公共标记的顺序很重要。<br/>由于使用这种方法无法保证公共标记的顺序，建议 Graphite 用户定义一个自定义的`MeterFilter`。|
|---|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

#### 6.5.2.每米属性

除了`MeterFilter`bean 之外，你还可以通过使用属性在每米的基础上应用一组有限的定制。每表自定义应用于以给定名称开始的任何表 ID。下面的示例禁用 ID 为的任何仪表。

属性

```
management.metrics.enable.example.remote=false
```

Yaml

```
management:
  metrics:
    enable:
      example:
        remote: false
```

以下属性允许按米定制：

|                                                     Property                                                     |说明|
|------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------|
|                                           `management.metrics.enable`                                            |是否防止仪表发出任何度量值.|
|                             `management.metrics.distribution.percentiles-histogram`                              |是否发布适合于计算可聚集（跨维度）百分位近似的直方图.|
|`management.metrics.distribution.minimum-expected-value`, `management.metrics.distribution.maximum-expected-value`|通过限制期望值的范围，发布更少的直方图桶。|
|                                  `management.metrics.distribution.percentiles`                                   |发布在应用程序中计算的百分位值|
|            `management.metrics.distribution.expiry`, `management.metrics.distribution.buffer-length`             |通过在可配置的缓冲区长度<br/>后旋转的环缓冲区中积累最近的样本，从而赋予它们更大的权重。|
|                                      `management.metrics.distribution.slo`                                       |使用由你的服务级别目标定义的桶发布累积直方图。|

有关`percentiles-histogram`、`percentiles`和`slo`背后的概念的更多详细信息，请参见千分尺文档的[“直方图和百分位”部分](https://micrometer.io/docs/concepts#_histograms_and_percentiles)。

### 6.6.指标端点

Spring 引导提供了一个`metrics`端点，你可以诊断地使用该端点来检查应用程序收集的指标。默认情况下端点不可用，必须公开。有关更多详细信息，请参见`MeterBinder`。

导航到`/actuator/metrics`将显示可用的仪表名称列表。你可以向下钻取以查看有关特定仪表的信息，方法是将其名称提供为选择器——例如，`/actuator/metrics/jvm.memory.max`。

|   |你在这里使用的名称应该与代码中使用的名称相匹配，而不是与它已被用于所运到的监视系统的命名约定规范化之后的名称相匹配，换句话说，<gt r=“1048”/，如果`jvm.memory.max`在普罗米修斯中出现`jvm_memory_max`，因为它的蛇形大小写命名约定，那么在检查`jvm.memory.max`端点中的仪表时，仍然应该使用`jvm.memory.max`作为选择器。|
|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

你还可以将任意数量的`tag=KEY:VALUE`查询参数添加到 URL 的末尾，以便在一个表上进行维度钻取——例如，`/actuator/metrics/jvm.memory.max?tag=area:nonheap`。

|   |报告的测量值是所有与仪表名称匹配的仪表的统计数据的*总和*，以及已应用的任何标记，<br/>在前面的示例中，返回的`Value`统计数据是“代码缓存”、“压缩类空间”的最大内存足迹的总和，以及堆的“元空间”区域。<br/>如果你只想看到“元空间”的最大大小，则可以添加一个额外的`tag=id:Metaspace`，即`/actuator/metrics/jvm.memory.max?tag=area:nonheap&tag=id:Metaspace`。|
|---| |

## 7. 审计

一旦 Spring 安全性发挥作用， Spring 启动执行器具有一个灵活的审计框架，该框架发布事件（默认情况下，“身份验证成功”、“失败”和“拒绝访问”异常）。这个特性对于报告和实现基于身份验证失败的锁定策略非常有用。

你可以通过在应用程序的配置中提供`AuditEventRepository`类型的 Bean 来启用审核。为了方便起见， Spring Boot 提供了`InMemoryAuditEventRepository`。`InMemoryAuditEventRepository`的功能有限，我们建议仅在开发环境中使用它。对于生产环境，考虑创建你自己的替代`AuditEventRepository`实现。

### 7.1.自定义审计

要定制已发布的安全事件，你可以提供你自己的`AbstractAuthenticationAuditListener`和`AbstractAuthorizationAuditListener`的实现。

你还可以为自己的业务事件使用审计服务。要做到这一点，可以将`AuditEventRepository` Bean 注入到你自己的组件中并直接使用它，或者使用 Spring `jvm.memory.max`发布`AbstractAuthenticationAuditListener`（通过实现`ApplicationEventPublisherAware`）。

## 8. HTTP 跟踪

你可以通过在应用程序的配置中提供`HttpTraceRepository`类型的 Bean 来启用 HTTP 跟踪。为了方便起见， Spring Boot 提供`/cloudfoundryapplication`，它存储最近 100 次（默认）请求-响应交换的跟踪。`InMemoryHttpTraceRepository`与其他跟踪解决方案相比是有限的，我们建议仅在开发环境中使用它。对于生产环境，我们建议使用生产就绪的跟踪或可观察性解决方案，例如 Zipkin 或 Spring Cloud Sleuth。或者，你可以创建自己的`HttpTraceRepository`。

你可以使用`httptrace`端点来获取有关存储在`HttpTraceRepository`中的请求-响应交换的信息。

### 8.1.自定义 HTTP 跟踪

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

## 9. 过程监控

在`spring-boot`模块中，你可以找到两个类来创建通常对过程监控有用的文件：

* `ApplicationPidFileWriter`创建一个包含应用程序 PID 的文件（默认情况下，在文件名为`application.pid`的应用程序目录中）。

* `WebServerPortFileWriter`创建一个包含运行中的 Web 服务器端口的文件（或多个文件）（默认情况下，在文件名为`application.port`的应用程序目录中）。

默认情况下，这些编写器不会被激活，但你可以启用它们：

* [通过扩展配置](#actuator.process-monitoring.configuration)

* [以编程方式启用过程监控](#actuator.process-monitoring.programmatically)

### 9.1.扩展配置

在`META-INF/spring.factories`文件中，你可以激活写入 PID 文件的侦听器（或多个侦听器）：

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

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

还可以通过调用`SpringApplication.addListeners(…​)`方法并传递适当的<br/>对象来激活侦听器。这个方法还允许你在`Writer`构造函数中自定义文件名和路径。

## 10. Cloud Foundry 支持

Spring Boot 的致动器模块包括额外的支持，该支持在部署到兼容的 Cloud Foundry 实例时被激活。`/cloudfoundryapplication`路径为所有`@Endpoint`bean 提供了一个可选的安全路由。

Spring 启动执行器信息增强了扩展的支持，使 Cloud Foundry 管理 UIS（例如你可以用于查看已部署应用程序的 Web 应用程序）得到增强。例如，应用程序状态页面可以包含完整的健康信息，而不是典型的“运行”或“停止”状态。

|   |普通用户无法直接访问<br/>路径。<br/>要使用端点，必须与请求一起传递有效的 UAA 令牌。|
|---|-----------------------------------------------------------------------------------------------------------------------------------------------------------|

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

如果要完全禁用`/cloudfoundryapplication`端点，可以在`application.properties`文件中添加以下设置：

属性

```
management.cloudfoundry.enabled=false
```

Yaml

```
management:
  cloudfoundry:
    enabled: false
```

### 10.2.Cloud Foundry 自签名证书

默认情况下，`/cloudfoundryapplication`Endpoints 的安全验证使 SSL 调用到各种 Cloud Foundry 服务。如果你的 Cloud Foundry UAA 或 Cloud Controller 服务使用自签名证书，则需要设置以下属性：

属性

```
management.cloudfoundry.skip-ssl-validation=true
```

Yaml

```
management:
  cloudfoundry:
    skip-ssl-validation: true
```

### 10.3.自定义上下文路径

如果服务器的上下文路径已被配置为`application.properties`以外的任何内容，那么在应用程序的根目录下，Cloud Foundry 端点是不可用的。例如，如果`server.servlet.context-path=/app`，则可在`/app/cloudfoundryapplication/*`上获得 Cloud Foundry 端点。

如果你希望 Cloud Foundry 端点始终在`/cloudfoundryapplication/*`上可用，那么无论服务器的上下文路径如何，你都需要在应用程序中显式地配置它。根据所使用的 Web 服务器的不同，配置也会有所不同。对于 Tomcat，你可以添加以下配置：

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

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

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

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

@Configuration(proxyBeanMethods = false)
public class MyCloudFoundryConfiguration {

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

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

        };
    }

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

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

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

}

```

## 11. 接下来要读什么？

你可能想了解有关绘图工具的信息，例如[Graphite](https://graphiteapp.org)。

否则，你可以继续阅读有关[“部署选项”](deployment.html#deployment)的内容，或者提前查看有关 Spring boot 的[构建工具插件](build-tool-plugins.html#build-tool-plugins)的一些深入信息。
