为了顺便熟悉SpringBoot3,本文将采用GraalVM + Springboot3!
关GraalVM与Springboot3的Demo,可以看我的这片文章:GraalVM + Native-Image + Springboot3(实战)
一、基础概念
1、何为“可观测性Observability”?
可观测性Observability:对线上的应用进行观测、监控、预警等:
-
健康状况 Health:【组件状态、存货状态】等;
-
运行指标 Metrics:【cpu、内存、垃圾回收、吞吐量、响应成功率】等;
-
链路追踪等;
2、Springboot为我们提供了一个开箱即用的可观测性解决方案:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
二、初始化一个Springboot3项目
创建完成后的pom.xml文件如下:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.1.1</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.jiguiquan.www</groupId> <artifactId>actuator</artifactId> <version>0.0.1-SNAPSHOT</version> <name>actuator</name> <description>actuator</description> <properties> <java.version>17</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.graalvm.buildtools</groupId> <artifactId>native-maven-plugin</artifactId> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludes> <exclude> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </exclude> </excludes> </configuration> </plugin> </plugins> </build> </project>
三、演示Actuator的简单使用/常用端点
1、在 application.yml 中增加如下配置:
management: endpoints: web: exposure: include: '*' # 通过web方式,暴露所有端点
2、此时我们在运行,即可看到 /actuator 接口暴露了很多端点:
其中,一切常用的端点介绍:
-
/actuator/health:健康状况的端点;
-
/actuator/metrics:指标数据;
-
/actuator/beans:当前IOC容器中有多少Bean;
-
/actuator/caches:服务当前的缓存情况;
-
/actuator/condition:当前服务中涉及到的条件,哪些条件是满足的,哪些条件是没满足的;
其中最重要的:/actuator/metrics 指标信息:
如果我们想看某个指标的详细信息:/actuator/metrics/指标名
有了这些指标信息,我们以后构建自己的监控平台面板将会变得非常容易!
3、以下以表格形式列举我们工作中可能会用到的端点:
端点 |
描述 |
auditevents | 暴露当前应用程序的审核事件信息。需要一个AuditEventRepository组件。 |
beans | 显示应用程序中所有Spring Bean的完整列表。 |
caches | 暴露当前的缓存情况。 |
conditions | 显示自动配置的所有条件信息,包括匹配或不匹配的原因。 |
configprops | 显示所有@ConfigurationProperties。 |
env | 暴露Spring的属性ConfigurableEnvironment |
flyway | 显示已应用的所有Flyway数据库迁移,需要一个或多个Flyway组件。 |
health | 显示应用程序运行状况信息。 |
httptrace | 显示HTTP跟踪信息(默认情况下,最近100个HTTP请求-响应)。需要一个HttpTraceRepository组件。 |
info | 显示应用程序信息。 |
integrationgraph | 显示Spring integrationgraph 。需要依赖spring-integration-core。 |
loggers | 显示和修改应用程序中日志的配置。 |
liquibase | 显示已应用的所有Liquibase数据库迁移。需要一个或多个Liquibase组件。 |
metrics | 显示当前应用程序的“指标”信息。 |
mappings | 显示所有@RequestMapping路径列表。 |
scheduledtasks | 显示应用程序中的计划任务。 |
sessions | 允许从Spring Session支持的会话存储中检索和删除用户会话。需要使用Spring Session的基于Servlet的Web应用程序。 |
shutdown | 使应用程序正常关闭。默认禁用。 |
startup | 显示由ApplicationStartup收集的启动步骤数据。需要使用SpringApplication进行配置BufferingApplicationStartup。 |
threaddump | 执行线程转储。 |
heapdump | 返回hprof堆转储文件。 |
jolokia | 通过HTTP暴露JMX bean(需要引入Jolokia,不适用于WebFlux)。需要引入依赖jolokia-core。 |
logfile | 返回日志文件的内容(如果已设置logging.file.name或logging.file.path属性)。支持使用HTTPRange标头来检索部分日志文件的内容。 |
prometheus | 以Prometheus服务器可以抓取的格式公开指标。需要依赖micrometer-registry-prometheus。 |
四、自定义监控端点
首先,如果想监控详细的健康状况,我们配置文件中还得增加一些配置:
management: endpoints: web: exposure: include: '*' # 通过web方式,暴露所有端点 endpoint: health: # 如果想展示所有组件健康状况的详细信息,下面两项必须配置,否则/health端点只会展示当前服务的存活情况 enabled: true show-details: always
1、自定义健康监控Health端点( 存活/死亡 ):核心 HealthIndicator
目标:监控 ZidanService 这个组件的健康状况:
被监控组件:ZidanService.java:
@Service public class ZidanService { // 随机返回一个整数,作为健康检查的依据 public int check(){ return new Random().nextInt(); } }
健康状况监控器类:
/** * 方法1、只需要实现HealthIndicator接口中的health()方法,即可来定制组件的健康状态; * 方法2、或者继承AbstractHealthIndicator抽象类,实现其doHealthCheck()抽象方法即可! */ @Component //public class ZidanServiceHealthIndicator implements HealthIndicator { public class ZidanServiceHealthIndicator extends AbstractHealthIndicator { @Autowired private ZidanService zidanService; @Override protected void doHealthCheck(Health.Builder builder) throws Exception { // 调用这个组件的check方法,然后根据返回结果,构建出一个存活结果 int result = zidanService.check(); // 我们就假设,如果result是偶数,则存活,是奇数,则死亡 if ((result % 2) == 0) { builder.up() .withDetail("code", "200") .withDetail("msg", "活得很好") .withDetail("data", "我是吉桂权") .build(); } else { builder.down() .withDetail("code", "500") .withDetail("msg", "我不太好") .withDetail("data", "嘿嘿") .build(); } } }
此时,我们再见调用Health端点,就可以看到ZidanService这个组件的健康状况了:
2、自定义指标监控Metrics端点( 次数、率 ):核心 MeterRegistry
目标:监控DemoController.demo()方法被调用了多少次!
DemoController.java:
@RestController public class DemoController { Counter counter; // 通过构造方法,注入MeterRegistry,从而给counter计数器赋值 public DemoController(MeterRegistry meterRegistry){ counter = meterRegistry.counter("jiguiquan.demo"); } @GetMapping("/demo") public void demo(){ counter.increment(); System.out.println("demo接口被调用了 " + counter.count() + " 次"); } }
此时,我们访问 /metrics/jiguiquan.demo 端点,就能看到我们自定义的计数指标信息!
五、整合Prometheus + Grafana
关于Prometheus 和 Grafana 的详细讲究,可以看我的另外的文章:
1、需要整合Prometheus,我们首先需要在项目中引入整合Prometheus的依赖:
这个依赖可以是 /metrics/prometheus 端点返回适配Prometheus的数据结构:
<dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-registry-prometheus</artifactId> <version>1.10.6</version> </dependency>
2、测试 /prometheus 的端点是否正常获取到数据:
3、没有问题,那么我们现在就将我们的代码拷贝到服务器上,进行打包编译:
# 将代码拷贝到服务器的/code/目录下 [root@jiguiquan actuator]# pwd /code/actuator [root@jiguiquan actuator]# ls pom.xml src # 3个命令,将actuator项目打包成二进制可执行文件: mvn clean package -DskipTests mvn spring-boot:process-aot mvn -Pnative native:build
4、通过编译好的二进制文件,快速启动actuator项目:
后台启动:
# 二进制文件启动 nohup target/actuator >actuator.log 2>&1 & ## 如果是jar包直接启动: nohup java -jar target/actuator-0.0.1-SNAPSHOT.jar >actuator.log 2>&1 &
服务运行正常!
六、配置Prometheus,从actuator服务的/prometheus端点上定时拉取数据:
关于Prometheus和Grafana的使用实战教程,可以看我的另一篇文章:Prometheus + Grafana实战
1、将Prometheus下载并解压到服务器的指定位置:
[root@jiguiquan prometheus]# ls grafana-8.3.6 prometheus-2.37.8 [root@jiguiquan prometheus]# cd prometheus-2.37.8/ [root@jiguiquan prometheus-2.37.8]# ls console_libraries consoles LICENSE NOTICE prometheus prometheus.yml promtool
2、修改Prometheus的核心配置文件prometheus.yml,添加一个新任务:
# my global config global: scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute. evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute. # scrape_timeout is set to the global default (10s). # Alertmanager configuration alerting: alertmanagers: - static_configs: - targets: # - alertmanager:9093 # Load rules once and periodically evaluate them according to the global 'evaluation_interval'. rule_files: # - "first_rules.yml" # - "second_rules.yml" # A scrape configuration containing exactly one endpoint to scrape: # Here it's Prometheus itself. scrape_configs: # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config. - job_name: "prometheus" static_configs: - targets: ["localhost:9090"] # 这就是我们的服务的端口,因为原定的9090和prometheus冲突了,所以我这里已经调整了actuator的端口 - job_name: "actuator" metrics_path: '/actuator/prometheus' #指定抓取的路径 static_configs: - targets: ["localhost:10000"] labels: nodename: 'actuator-demo'
3、nohup后台启动prometheus服务:
nohup ./prometheus --config.file=prometheus.yml > prometheus.log 2>&1 &
4、访问 http://ip:9090/targets 端点,可以查看数据采集情况:
数据采集正常!
七、配置Grafana面板,展示actuator服务监控状态
1、依然显示将Grafana下载解压到服务器的指定位置:
[root@jiguiquan prometheus]# ls grafana-8.3.6 prometheus-2.37.8 [root@jiguiquan prometheus]# cd grafana-8.3.6/ [root@jiguiquan grafana-8.3.6]# ls bin conf LICENSE NOTICE.md plugins-bundled public README.md scripts VERSION
2、暂时我们不修改Gafana的配置文件,直接nohup后台运行:
nohup bin/grafana-server > grafana.log 2>&1 &
3、通过 http://ip:3000 访问Grafana服务:
Grafana默认账号密码为:admin :admin,登录时我们可以修改下次密码,也可以Skip跳过!
4、登录后,我们首先需要先配置一个Prometheus数据源:
5、去官方Dashboard市场找一个好看的仪表板(如果有实力,也可以自己搭建):
官网Dashboard下载页面:https://grafana.com/grafana/dashboards/
我选择的是这个:https://grafana.com/grafana/dashboards/12900-springboot-apm-dashboard/
复制它的Dashboard ID或者下载JSON文件都可以:
6、在Grafana中导入Dashboard:
7、配置完成后的效果如下图所示:
到这里,整个Springboot项目的指标监控全流程就走通了,以后的项目中,可以适当的暴露这些监控端点哦,还可以自定义自己的“健康状况”或“运行指标”信息!