《SpringBoot 3入门与应用实战》第 15 章 生产级特性 监控端点 Endpoints 阅读笔记一 参考资料二 笔记总结第 15 章 生产级特性本章主要内容Spring Boot 的监控组件 ActuatorActuator 的监控端点和监控指标使用 Spring Boot Admin 管理 Spring Boot 应用监控体系的使用。在企业级应用中对应用程序进行运行状态的监控是必不可少的。Spring Boot 提供了生产级的特性指标监控和管理对应的 Spring Boot 组件为 Actuator。15.1 Spring Boot ActuatorSpring Boot 中用于监控和管理的组件是 Spring Boot Actuator只需要引入 Spring Boot Actuator 的场景启动器就可以使用。Spring Boot Actuator 还提供了许多可配置项甚至支持自定义监控指标我们可以根据具体的实际情况进行指标定制。15.1.1 背景与方案如果我们需要实时了解 IOC 容器中的 Bean 组件有哪些需要如何处理借助 Web 工程编写一个 Controller将 ApplicationContext 注入并调用相应的方法获取这的确是一种方案但是必然会产生编码成本。packagecom.yangjunbo.monitoring.controller;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.beans.factory.config.BeanDefinition;importorg.springframework.context.ConfigurableApplicationContext;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.bind.annotation.RestController;importjava.util.HashMap;importjava.util.Map;/** * ClassName: BeansController * Package: com.yangjunbo.monitoring.controller * Description: * * Author 杨钧博 * Create 2026/8/2 20:40 * Version 1.0 */RestControllerRequestMapping(/beans)publicclassBeansController{AutowiredprivateConfigurableApplicationContextapplicationContext;RequestMapping()publicMapString,ObjectgetAllBeans(){MapString,ObjectresultnewHashMap();// 获取容器中所有 Bean 的名称String[]beanNamesapplicationContext.getBeanDefinitionNames();for(StringbeanName:beanNames){MapString,StringbeanInfonewHashMap();try{// 获取 Bean 的定义元数据BeanDefinitionbeanDefinitionapplicationContext.getBeanFactory().getBeanDefinition(beanName);beanInfo.put(beanClass,beanDefinition.getBeanClassName());beanInfo.put(scope,beanDefinition.getScope());beanInfo.put(isSingleton,String.valueOf(beanDefinition.isSingleton()));// 尝试获取当前运行时的实际对象类型防止懒加载或代理导致的信息不准ObjectbeanapplicationContext.getBean(beanName);beanInfo.put(runtimeType,bean.getClass().getName());}catch(Exceptione){// 某些特殊的 Bean 可能在获取时抛出异常如未初始化的懒加载BeanbeanInfo.put(error,e.getMessage());}result.put(beanName,beanInfo);}MapString,ObjectresponsenewHashMap();response.put(totalBeans,beanNames.length);response.put(beans,result);returnresponse;}}再举一个场景的例子我们需要了解当前Spring Boot应用中有哪些自动配置类生效以往我们只能通过修改Spring Boot的日志级别使自动装配结果报告输出到日志文件中但即便如此我们想要查看日志文件也不是很方便。logging:level:org.springframework.boot.autoconfigure:debugfile:name:logs/monitoring-demo-01.log针对上述种种问题Spring Boot Actuator 应运而生。整合 Spring Boot Actuator 之后我们可以非常方便地获取上述的所有信息而且获取的结果比我们手动获取的还要全面、规整。15.1.2 整合使用在Spring Boot应用中使用Actuator的方式非常简单引入Spring Boot Actuator的场景启动器即可。使用浏览器访问 http://localhost:8080/actuator/health 接口发现浏览器收到了一条只包含一个 status 的 JSON 数据且 status 为UP这就代表当前 Spring Boot 应用的状态是正常运行的倘若出现 DOWN 的状态则代表当前 Spring Boot 应用宕机需要处理异常情况。15.2 监控端点 EndpointsSpring Boot Actuator 提供了非常多的监控端点按照功能类别可以大致划分为以下 3 类。JMXJava Management Extensions即 Java 管理扩展是 Java 平台提供的一套标准化框架和 API主要用于管理和监控 Java 应用程序。了解即可不是当前学习的内容。当前主要学习 HTTP 的方式访问监控端点。监控类可以获得当前 Spring Boot 应用的状态、监控度量指标。端点 ID描述health健康状态检查默认开启 HTTP 和 JMX 端点。metrics监控度量指标信息默认只开启 JMX 端点。prometheus对接 Prometheus 监控系统提供可以被 Prometheus 解析的监控信息只有 HTTP 端点且默认关闭。信息类可以获得当前 Spring Boot 应用中客观存在的信息这部分端点中大部分默认开启 JMX 端点对于 HTTP 端点默认全部关闭。端点 ID描述beans获得 IOC 容器中的所有 Bean 信息conditions获得注解配置类的条件装配信息和装配结果configprops获得 Spring Boot 中使用 ConfigurationProperties 注解绑定的配置属性对象env获得当前应用的所有配置属性和值mappings获得 WebMvc 或 WebFlux 应用中使用 RequestMapping 注解编写的 Handler 映射信息info返回自定义的应用基本信息caches获得 IOC 容器中设置的缓存信息logfile如果配置了 logging.file.name 或 logging.file.path 属性则会返回日志文件内容仅 HTTP 端点。httpexchanges获得最近 100 条 HTTP 请求跟踪信息操作类可以对正在运行的应用进行修改部分端点也兼顾信息获取功能。端点 ID描述loggers获取或修改指定日志的级别使用 HTTP 端点时发送 GET 请求为获取发送 POST 请求则为修改。sessions当应用整合 Spring Session 时可以获取或移除指定 session针对普通的嵌入式 Web 容器无效shutdown关闭应用使用优雅关闭机制该端点默认关闭。headdump执行 head dump 操作生成 dump 文件threaddump执行 thread dump 线程转储动作同样生成 dump 文件。根据上面的描述可知默认情况下大部分 HTTP 端点是不可访问的我们需要手动开启开启的方式是在全局配置文件中添加两行配置其中 management. endpoints.web.exposure.include 可以指定准许访问的具体端点名称可以直接指定 “*”代表对于所有开启的端点全部开放访问。management:endpoints:web:exposure:include:*15.2.1 healthhealth 这个端点默认状态下访问时只会得到一个 status 信息然而当我们在全局配置文件中配置 management.endpoint.health.show-details always 后重启应用再次访问 /actuator/health 端点时发现返回的信息有所增多。很明显更详细的信息主要包括磁盘空间使用、当前工程的路径等如果我们的工程中引入了数据源信息则此处还会展示与数据库相关的健康检查信息。management:endpoints:web:exposure:include:*endpoint:health:show-details:always15.2.2 beans如果我们需要知悉其他监控端点的访问路径Spring Boot Actuator 提供的方案是直接访问 /actuator 路径。下面我们访问/actuator/beans端点beans端点返回的数据如下15.2.3 conditionsconditions端点返回的信息是“配置类的条件装配报告”​它可以展示Spring Boot应用中的注解配置类和自动装配是否生效以及对应生效/不生效的依据。positiveMatches条件装配生效的自动配置类。negativeMatches条件装配没有生效的自动配置类。unconditionalClasses没有条件装配的自动配置类。15.2.4 configprops 和 envconfigprops 意为“配置属性”​它可以将 Spring Boot 中使用 ConfigurationProperties 或 EnableConfigurationProperties 注解引用的那些配置属性对象都列举出来展示其中的配置属性和值。默认情况下使用 configprops 端点查看配置属性值时不会展示需要我们使用配置项放开显示。与 configprops 相关的另一个端点是 env它可以展示包括 Spring Boot 全局配置属性在内的所有配置属性包括 systemProperties、systemEnvironment整合 WebMvc 的工程还会展示 ServletContext 的初始化参数 servletContextInitParams。简单观察和总结可以得出systemProperties 保存的是与当前 Java 环境和应用进程相关的信息systemEnvironment 则是直接移植的操作系统环境变量。15.2.5 mappingsmappings 端点返回的是当前应用中的所有 URI 映射规则只要是使用 ControllerRequestMapping 注解定义的 Handler都会被收集起来并在该端点展示。我们访问 /actuator/mappings 端点会发现返回的数据量非常大其中很多映射器实际上是 Spring Boot Actuator 提供的其中包含请求方式、请求所需的参数、请求头、对应的Handler位置等非常齐全。15.2.6 loggersloggers 端点是一个具备双重功能的端点如果使用 GET 方式请求该端点可以得到当前应用此时此刻的日志级别它包含 3 个部分分别是levels当前应用支持的所有日志级别​、loggers所有可配置和获取的日志级别​、groups日志分组​对应 6.4 节讲解的内容。如果使用 POST 方式请求该端点并携带 URL 参数可修改指定包/类的日志级别例如声明 com.linkedbear.springboot 包下的所有日志级别都改为 DEBUG。当修改完毕后再次发送 GET 请求获取日志级别可以发现这次包括 com.linkedbear.springboot 包以及内部包含的所有子元素的日志级别都被改为 DEBUG。15.2.7 infoinfo 端点是一个比较特殊的端点它可以返回与当前应用相关的一些信息但是默认状态下这个端点不会返回任何信息。我们可以通过 Spring Boot Actuator 提供的两种方式扩展 info 端点的信息分别是声明式定制和编程式定制两种方式。声明式定制 info 端点的方式非常简单只需要在 Spring Boot 全局配置文件中声明一组 info.* 的配置属性比如我们在配置文件中声明当前的应用名和版本号。声明完毕后重启应用访问 /actuator/info 端点就可以得到相应的 JSON 数据。相较于声明式定制而言使用编程式定制 info 端点的灵活性更高而且可以动态读取其他信息。编程式定制 info 端点时需要我们向 IOC 容器中注册一个类型为 InfoContributor 的组件。请读者注意一个细节通过 InfoContributor 定制的 info 数据与声明式定制的数据可以共存不会报错如果两者定义了同一个属性则以 InfoContributor 中定制的为准。15.2.8 扩展health除了 info 信息可以扩展health 信息也可以扩展。虽然 Spring Boot 给我们提供的端点信息已经足够丰富但实际项目开发中难免还是会出现需要扩展的场景。从 Spring Boot 2.x 开始扩展端点信息的方式变得更加简单、更容易操作同时使用的 API 更容易被记住下面我们来扩展health 端点的内容。在 15.2.1 节中已经提到Spring Boot Actuator 可以针对 Spring Boot 已经整合的场景自动加入健康检查信息的返回但是对于 Spring Boot 没有整合的框架或者第三方技术而言Spring Boot 无法探测和感知有哪些指标需要监控和反馈此时就需要我们自行定义和扩展对应的健康检查信息。扩展健康检查信息的方式不复杂只需要编写一个 HealthIndicator 的实现类或 AbstractHealthIndicator 的子类并注册到 IOC 容器。需要注意一个细节HealthIndicator 的实现类中的前缀名叫什么最终反映到 health 端点中对应的监测属性名就叫什么比如 AnimalHealthIndicator中最终呈现的属性名就叫 animal​。构造健康检查信息的方式也不难直接操作 Health.Builder 建造器的方法即可返回宕机 ( DOWN ) 信息的方法是直接调用 Health.Builder 的 down 方法除了响应 DOWN 信息还可以调用 builder 的 withDetail 方法附加一条额外的信息或调用withDetails 方法直接传入 Map 对象附加一组额外信息。15.2.9 扩展监控端点以上测试的端点都是 Spring Boot Actuator 内置的端点如果这些端点无法满足我们的需求或者我们想要自定义一些端点Spring Boot 也提供了扩展方案编写监控端点就像编写 WebMvc 的 Controller 一样简单下面简单演示。监控端点的访问行为分为获取、修改、移除这非常类似于 HTTP 请求中的 GET、PUT、DELETE 方式。Spring Boot Actuator 提供了几个注解供我们编写监控端点。与 WebMvc 的 Controller 类似当我们给一个 Bean 标注 Endpoint 注解就代表当前 Bean 具有了监控端点暴露的能力该注解类似于 WebMvc 的 Controller 注解不同的是Endpoint 不是 Component 的派生注解所以同时标注 Endpoint 和Component 注解的 Bean 才算作一个监控端点的 Bean标注获取、修改、移除动作的注解分别是 ReadOperation、WriteOperation、DeleteOperation分别对应 WebMvc 中的 GetMapping、PutMapping、DeleteMapping不同的是RequestMapping 的派生注解可以指定请求路径 URI而监控端点不存在 URI 一说因为 Endpoint 注解中的端点名称已经是URI的名称。15.2.10 保护端点安全到目前为止我们访问Actuator的所有监控端点都可以直接访问成功没有任何阻碍这对于上线后的应用而言是非常不安全的因此我们必须考虑将这些监控端点予以保护。Spring Boot Actuator保护监控端点的方案主要有两种一一来看。借助Spring Security另起监听端口将所有的监控端点暴露到另一个端口上。默认情况下Spring Boot Actuator 的所有监控端点会共用 WebMvc 中的 Web 容器端口对外提供服务我们可以通过配置 Actuator 的监听端口和 context-path使监控端点单独暴露在另一套端点中这样配合服务器的防火墙等措施也可以保证监控端点不被外部访问。15.2.11 使用JMX访问本节的最后我们来补充使用 JMX 访问端点的方式。Spring Boot Actuator 默认不会开放 HTTP 协议的端点这是因为默认情况下使用 HTTP 端点会返回与应用服务甚至服务器相关的敏感信息所以 Spring Boot Actuator 选择了比较谨慎保守的方案。相较于 HTTP 而言使用 JMX 协议访问会安全一些Spring Boot Actuator 的绝大多数端点默认开启了基于 JMX 的访问而访问 JMX 端点的工具可以是 JConsole 或 JVisualVM它们都是 JDK 自带的工具我们可以直接使用。以 JConsole 为例我们从 JDK 的安装目录下就可以找到 JConsole 的运行程序双击程序即可运行。打开 JConsole 后会弹出当前主机上运行的所有应用程序我们选择当前运行的 SpringBootActuatorApplication 并单击下方的“连接”按钮即可进入监控管理控制台选择上方的 MBean 选项卡之后依次选择左侧的 org.springframework.boot→ Endpoint即可看到当前的所有监控端点双击某个端点即可查看此时的状态。