【监控】spring actuator源码速读

简介: 【监控】spring actuator源码速读

1.前言

版本:spring-boot-starter-actuator  2.6.3

阅读源码一定要带着疑问去阅读,这个疑问就是你阅读的主线,不然在浩如烟海的源码里面很容易迷路。我们当前的疑问是什么?之前我们已经聊过spring actuator的使用了:

本文要搞清楚的两个问题在于:

  • EndPoint是怎么被注入IOC又怎么暴露出去能通过HTTP访问到的?
  • EndPoint是怎么实现监控能力的?

2.先搂一眼EndPoint

首先我们找一个EndPoint来看看,此处以HealthEndPoint为例。点看源码我们可以看到这个EndPoint被@EndPoint注解所注释,id为health。然后其中的2个方法被@ReadOperation所注释:

这里其实猜都能猜到被@EndPoint注解,然后被注解的类被归类为EndPoint,然后被集中暴露出去,变成可访问的。

3.EndPoint如何被注入

我们是通过stater来引入actuator的,Spring Boot体系内如何注入stater的?那肯定是通过autoConfiguration来的撒。点进actuator的配置文件也可以看到:


于是我们来到spring-boot-starter-actuator来看看,看看它的spring.factories里面注入了些什么:


见名知意了,这些众多的XXXautoConfiguration是拿来做什么的就不必多说了吧,health、metrics......分门别类,各种EndPoint的autoConfiguration。

我们来看看HealthEndpointAutoConfiguration里面做了什么:

其实就是加载了HealthEndpointConfiguration、ReactiveHealthEndpointConfiguration、HealthEndpointWebExtensionConfiguration、HealthEndpointReactiveWebExtensionConfiguration这几个类

@Configuration(
    proxyBeanMethods = false
)
@ConditionalOnAvailableEndpoint(
    endpoint = HealthEndpoint.class
)
@EnableConfigurationProperties({HealthEndpointProperties.class})
@Import({HealthEndpointConfiguration.class, ReactiveHealthEndpointConfiguration.class, HealthEndpointWebExtensionConfiguration.class, HealthEndpointReactiveWebExtensionConfiguration.class})
public class HealthEndpointAutoConfiguration {
    public HealthEndpointAutoConfiguration() {
    }
}

我们先看HealthEndpointConfiguration,它里面向IOC中注入了health的Registry,HealthContributorRegistry中注册了HealthContributor类型的实体。

我们随便打开一个health的EndPoint,发现它都继承同一个父类:

而这个父类实现了HealthContributor接口:

所以其实就是在将注册器注入IOC的时候,就将所有属于该类型的EndPoint注册到注册器中了。

4.EndPoint如何被暴露

4.1.如何通过http暴露

在SpringBoot体系中,谁来负责http请求?那当然是SpringMVC的DispatcherServlet。把path和对应处理的类注册到DispatcherServlet中就行了。spring actuator就是这样对外通过HTTP的方式暴露EndPoint的。

回到spring.factories,找ManagementContextAutoConfiguration,这个类中完成了通过HTTP的方式来暴露EndPoint的过程:

这个类的代码并不多,我们去掉不要的部分,把和对外暴露EndPoint相关的代码保留,来读一下:

@ManagementContextConfiguration(
    proxyBeanMethods = false
)
@ConditionalOnWebApplication(
    type = Type.SERVLET
)//只能在Web环境中生效
public class ServletEndpointManagementContextConfiguration {
    public ServletEndpointManagementContextConfiguration() {
    }
    @Configuration(
        proxyBeanMethods = false
    )
    @ConditionalOnClass({DispatcherServlet.class})//当SpringMVC存在时向IOC中注入
    public static class WebMvcServletEndpointManagementContextConfiguration {
        public WebMvcServletEndpointManagementContextConfiguration() {
        }
        @Bean
        public ServletEndpointRegistrar servletEndpointRegistrar(WebEndpointProperties properties, ServletEndpointsSupplier servletEndpointsSupplier, DispatcherServletPath dispatcherServletPath) {
            return new ServletEndpointRegistrar(dispatcherServletPath.getRelativePath(properties.getBasePath()), servletEndpointsSupplier.getEndpoints());//核心的一步,将EndPoint和对于的Path注册给DispatcherServlet
        }
    }
}

最后就是开头我们看见的在HealthEndPoint被@ReadOperation注解的方法,就相当于@RequetMapping,拿来处理读请求的。

4.2.如何通过jmx暴露

jmx的对外暴露更简单。直接找JmxEndpointAutoConfiguration:

进去整个逻辑一目了然,去扫Jmx的EndPoint然后注册进mBeanServer里:

5.EndPoint是怎么实现监控能力的

spring actuator获取各种监控的值是怎么获取到的?

内置指标获取: Spring Boot 提供了一些内置的监控指标获取器,用于获取常见的监控数据,比如 JVM 内存使用情况、系统负载、数据库连接池状态等。这些指标获取器会周期性地获取数据,并将其暴露为 Actuator 端点,以便外部系统或者工具可以通过相应的接口来获取。例如,MemoryHealthIndicator 获取 JVM 内存使用情况,DataSourceHealthIndicator 获取数据库连接池状态等。


自定义指标获取: 除了内置的指标获取器外,开发者还可以通过实现 HealthIndicator 接口来自定义监控指标获取器,用于获取应用程序特定的监控数据。HealthIndicator 接口定义了一个 health() 方法,用于返回健康状态信息。开发者可以在 health() 方法中编写自定义的监控逻辑,比如检查某个依赖服务的可用性、计算某个指标的值等。


JMX 获取: Spring Actuator 还可以通过 Java Management Extensions (JMX) API 来获取一些系统级的监控数据,比如 JVM 运行时信息、操作系统信息等。Spring Actuator 中的一些监控指标获取器会使用 JMX API 来获取数据,然后将其暴露为 Actuator 端点。例如,JvmInfoContributor 使用 JMX API 来获取 JVM 运行时信息。


系统调用获取: 有些监控数据可能需要通过系统调用来获取,比如获取操作系统的 CPU 使用率、磁盘使用情况等。Spring Actuator 中的一些监控指标获取器会使用系统调用来获取这些数据,然后将其暴露为 Actuator 端点。

6.知道这些的意义是什么

本文是作者java监控系列文章的第三篇,之前两篇文章我们着重讲了java监控的基石——JMX。

【JMX】JAVA监控的基石-CSDN博客

详解tomcat中的jmx监控-CSDN博客

在spring actuator里面我们知道了目前市面上一个成熟的框架是如何通过http、JMX等不同方式来对外暴露监控能力的。基本上走到这里我们就已经对JAVA整个的监控技术体系最核心的部分有了认识了。作为监控框架来说核心点有哪些?无非是:

  • 获取数据
  • 对外暴露口子

监控的核心肯定是怎么获取数据以及如何将获取的数据暴露出去,只要这两点搞定了,后面的对接各种可视化平台就很好办了。所有知道为啥这篇文章为啥要关心spring actuator这些地方了吧,主要是看看实现思想。

目录
相关文章
|
14天前
|
监控 Java 数据库连接
Spring Boot中的健康检查和监控
Spring Boot中的健康检查和监控
|
4天前
|
监控 Java 微服务
Spring Boot微服务部署与监控的实战指南
【7月更文挑战第19天】Spring Boot微服务的部署与监控是保障应用稳定运行和高效维护的重要环节。通过容器化部署和云平台支持,可以实现微服务的快速部署和弹性伸缩。而利用Actuator、Prometheus、Grafana等监控工具,可以实时获取应用的运行状态和性能指标,及时发现并解决问题。在实际操作中,还需根据应用的具体需求和场景,选择合适的部署和监控方案,以达到最佳效果。
|
14天前
|
Prometheus 监控 Cloud Native
使用Spring Boot和Prometheus进行监控
使用Spring Boot和Prometheus进行监控
|
20天前
|
JavaScript Java 数据安全/隐私保护
基于SpringBoot+Vue毕业生信息招聘平台系统【源码+论文+演示视频+包运行成功】_基于spring vue的校园招聘系统源码(2)
基于SpringBoot+Vue毕业生信息招聘平台系统【源码+论文+演示视频+包运行成功】_基于spring vue的校园招聘系统源码
28 0
基于SpringBoot+Vue毕业生信息招聘平台系统【源码+论文+演示视频+包运行成功】_基于spring vue的校园招聘系统源码(2)
|
21天前
|
运维 Prometheus 监控
Spring Boot中使用Actuator监控应用状态
Spring Boot中使用Actuator监控应用状态
|
25天前
|
运维 监控 Java
Spring Boot中使用Actuator进行监控
Spring Boot中使用Actuator进行监控
|
27天前
|
Java Spring 容器
解读spring5源码中实例化单例bean的调用链
解读spring5源码中实例化单例bean的调用链
|
15天前
|
监控 安全 Java
解析Spring Boot中的Actuator端点
解析Spring Boot中的Actuator端点
|
20天前
|
JavaScript Java 关系型数据库
基于SpringBoot+Vue毕业生信息招聘平台系统【源码+论文+演示视频+包运行成功】_基于spring vue的校园招聘系统源码(1)
基于SpringBoot+Vue毕业生信息招聘平台系统【源码+论文+演示视频+包运行成功】_基于spring vue的校园招聘系统源码
23 0
|
20天前
|
Prometheus 监控 Cloud Native
Spring Boot中使用Micrometer进行指标监控
Spring Boot中使用Micrometer进行指标监控