 应用监控介绍
应用监控介绍
  # 13.1 应用监控介绍
Spring Boot 包含了许多附加功能,可以帮助你在将应用程序部署到生产环境时监视和管理它。你可以选择使用 HTTP 端点或与 JMX 一起管理和监视应用程序。你可以在你的应用程序中收集审计数据、运行状况和度量(如,性能)数据。SpringBoot 自带的监控功能Actuator (opens new window)(执行器)组件,就可以帮助开发人员实现对程序内部运行情况的监控,比如监控服务器状况、Bean 加载情况、环境变量、日志信息、线程信息等。
执行器是一个制造业术语,指的是用于移动或控制东西的一个机械装置,一个很小的改变就能让执行器产生大量的运动。
# 13.1.1 启用 Actuator
Spring Boot Actuator 模块为应用在生产场景(Production-ready)的监控内置提供了大量的便捷服务。
启动 SpringBoot 的 Actuator 模块,最简单的方式就是添加spring-boot-starter-actuator启动器(Spring Boot Starter)。
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
</dependencies>
2
3
4
5
6
# 13.1.2 端点
执行器端点(endpoints)可用于监控应用及与应用进行交互,Spring Boot 包含很多内置的端点,你也可以添加自己的。例如,health 端点提供了应用的基本健康信息。
每个端点都可以启用或禁用。你可以通过配置文件(application.properties 或 application.yml)控制是否启用每一个内置的端点。然后,通过 JMX 或 HTTP 远程访问这些启用并暴露的端点。端点的 ID 映射到一个带/actuator前缀的 URL。例如,health 端点默认映射到/actuator/health。
在 Spring Boot 2.2 中,默认 HTTP 上打开的端点只有 health 和 info,其他端点默认关闭。
| id | 描述 | 
|---|---|
| auditevents | 显示当前应用程序的审计事件信息,需要配置有 AuditEventRepositoryBean | 
| beans | 显示应用中 Spring Beans 的完整列表 | 
| caches | 显示可用缓存信息 | 
| conditions | 显示自动装配类的状态及及应用信息 | 
| configprops | 显示所有 @ConfigurationProperties 列表 | 
| env | 显示 ConfigurableEnvironment 中的属性 | 
| flyway | 显示 Flyway 数据库迁移信息 | 
| health | 显示应用的健康信息(未认证只显示 status,认证显示全部信息详情) | 
| httptrace | 显示 HTTP 跟踪信息(默认显示最后 100 个 HTTP 请求 - 响应) | 
| info | 显示任意的应用信息 | 
| integrationgraph | 显示 Spring Integration graph, 需要依赖 spring-integration-core。 | 
| loggers | 显示或修改应用程序内的日志配置。 | 
| liquibase | 展示 Liquibase 数据库迁移 | 
| metrics | 展示当前应用的 metrics 信息 | 
| mappings | 显示所有 @RequestMapping 路径集列表 | 
| scheduledtasks | 显示应用程序中的计划任务 | 
| sessions | 允许从 Spring 会话支持的会话存储中检索和删除用户会话。 | 
| shutdown | 允许应用以优雅的方式关闭(默认情况下不启用) | 
| threaddump | 执行一个线程 dump | 
如果你的应用是一个 Web 应用(Spring MVC,Spring WebFlux 或者 Jersey),你还能使用如下的这几个额外的监控端点:
| ID | Description | 
|---|---|
| heapdump | 返回一个 hprof堆 dump 文件。Returns anhprofheap dump file. | 
| jolokia | 通过 HTTP 暴露 JMX beans(当 Jolokia 在类路径上时,WebFlux 不可用)。需要依赖jolokia-core。 | 
| logfile | 返回日志文件内容(如果设置了 logging.file.nameorlogging.file.path属性的话),支持使用 HTTP Range 头接收日志文件内容的部分信息。 | 
| prometheus | 以可以被 Prometheus 服务器抓取的格式显示度量(metrics)信息。需要依赖 micrometer-registry-prometheus。 | 
# 13.1.3 启用端口
默认情况下,除 shutdown 以外的所有端点均已启用。要配置单个端点的启用,请使用management.endpoint.<id>.enabled属性。以下示例启用 shutdown 端点:
management.endpoint.shutdown.enabled=true
另外可以通过management.endpoints.enabled-by-default来修改全局端点默认配置,以下示例启用 info 端点并禁用所有其他端点:
management.endpoints.enabled-by-default=false
management.endpoint.info.enabled=true
2
需要注意的是,禁用的端点将从应用程序上下文中完全删除。如果您只想更改端点暴露情况,请改为使用include和exclude属性。
- include 属性列出了公开的端点的 ID,exclude 属性列出了不应该公开的端点的 ID;
- exclude 属性优先于 include 属性。包含和排除属性都可以使用端点 ID 列表进行配置。
management.endpoints.web.exposure.include=*
management.endpoints.web.exposure.exclude=env,beans
2
由于端点可能包含敏感信息,因此应仔细考虑如何暴露它们。
Spring Boot 默认暴露端点情况如下表所示:
| 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 | Yes | 
| 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 | 
| scheduledtasks | Yes | No | 
| sessions | Yes | No | 
| shutdown | Yes | No | 
| threaddump | Yes | No | 
以下为在学习过程中的配置:启用了 shutdown 端点,暴露除了 info 之外的所有端口:
management:
  endpoint:
    shutdown:
      enabled: true
  endpoints:
    web:
      exposure:
        include: "*"
        exclude:
        - info
2
3
4
5
6
7
8
9
10

# 13.1.4 保护端点
我们应该时刻注意保护 HTTP 端点,其保护方式与使用其他任何敏感网址的方式相同。如果存在 Spring Security,则默认使用 Spring Security 的内容协商策略(content-negotiation strategy)保护端点。例如,如果你希望为 HTTP 端点配置自定义的安全性,比方说只允许具有特定角色的用户访问它们,Spring Boot 提供了一些方便的RequestMatcher对象,可以与 Spring Security 结合使用。
一个典型的 Spring Security 配置可能看起来像下面的例子:
@Configuration(proxyBeanMethods = false)
public class ActuatorSecurity extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeRequests((requests) ->
                requests.anyRequest().hasRole("ENDPOINT_ADMIN"));
        http.httpBasic();
    }
}
2
3
4
5
6
7
8
9
10
11
上例使用EndpointRequest.toAnyEndpoint()将请求与所有端点进行匹配,然后确保所有端点都具有 ENDPOINT_ADMIN 角色。
当然,如果我们的应用程序部署在防火墙后面,可能更喜欢所有的执行器端点都可以在无需验证的情况下进行访问。但是也要注意的是,内网有时候也不是很安全,应用程序可能会遇到有意或无意的危险操作。
我们可以通过更改management.endpoints.web.exposure.include属性来完成此操作。
management.endpoints.web.exposure.include=*
此外,如果存在 Spring Security,则需要添加自定义安全配置,以允许对端点进行未经身份验证的访问,如以下示例所示:
@Configuration(proxyBeanMethods = false)
public class ActuatorSecurity extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.requestMatcher(EndpointRequest.toAnyEndpoint()).authorizeRequests((requests) ->
            requests.anyRequest().permitAll());
    }
}
2
3
4
5
6
7
8
9
10
