05. Springboot admin集成Actuator(一)
目录
1、前言
2、Actuator监控端点
2.1、健康检查
2.2、信息端点
2.3、环境信息
2.4、度量指标
2.5、日志文件查看
2.6、追踪信息
2.7、Beans信息
2.8、Mappings信息
3、快速使用
2.1、添加依赖
2.2、添加配置文件
2.3、启动程序
4、自定义端点Endpoint
5、自定义health
6、附录
7、小结
1、前言
Spring Boot Actuator是Spring Boot提供的一个用于监控和管理应用程序的扩展模块。Actuator通过HTTP端点和JMX(Java Management Extensions)提供了一系列功能,包括查看应用程序的运行状况、度量指标、日志、追踪和应用信息。它为开发人员和运维人员提供了方便的手段来监控和管理Spring Boot应用。
2、Actuator监控端点
Actuator提供了一系列内置的端点(EndPoints)用于查看应用程序的运行状况、运行情况、指标等信息。其中主要提供了如下一些端点:
2.1、健康检查
HTTP端点:`/actuator/health`。提供了应用程序的健康状态,包括磁盘空间、数据库连接等信息。健康检查对于监控和负载均衡非常有用。返回的状态包括 UP(正常)、DOWN(异常)和 OUT_OF_SERVICE(维护中)等。
2.2、信息端点
HTTP端点:`/actuator/info`。提供了应用程序的自定义信息,可以在配置文件中定义,用于展示应用的版本、描述等。这些信息通常来源于应用程序的配置文件或构建系统。
2.3、环境信息
HTTP端点:`/actuator/env`。显示应用程序的环境属性,包括配置属性、系统属性等。可以通过添加参数来查看特定属性的值,如:/actuator/env/server.port。
2.4、度量指标
HTTP端点:`/actuator/metrics`。提供了应用程序的度量指标,例如内存使用、线程池状态、HTTP请求等,对性能分析和优化非常有帮助。如:/actuator/metrics/jvm.memory.used。
2.5、日志文件查看
HTTP端点:`/actuator/logfile`。允许查看应用程序的日志文件内容,方便进行故障排除。
2.6、追踪信息
HTTP端点:`/actuator/trace`。提供了应用程序的请求追踪信息,显示HTTP请求的调用链,便于跟踪请求的处理过程。
2.7、Beans信息
HTTP端点:`/actuator/beans`。显示所有在Spring应用程序上下文中注册的Beans信息,包括它们的名称、类型等。
2.8、Mappings信息
HTTP端点:`/actuator/mappings`。 显示所有的URI映射,展示了请求如何被映射到控制器方法上。
3、快速使用
了解了Actuator的各个主要端点以及他们的作用后,我们便可以选择适当的端点作为我们的监控行为,集成到项目中。
基础环境:SpringBoot-2.7.14,JDK-17.0.2。构建基础springboot demo工程。
3.1、添加依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
3.2、添加配置文件
spring:application:name: springboot-actuator-demo
server:port: 8080management:server:port: 8081 # 指定了actuator服务端口endpoints:web:exposure:include: '*' # 表示开启所有端点,如果指定具体多个端点,可以用,隔开。如health,info
3.3、启动程序
启动日志中可以看到启动了actuator端口为8081,且访问路径为/actuator。我们访问下http://localhost:8081/actuator:
可以看到actuator返回了一列指标的访问连接。
接着继续访问给定的连接,实际上就是http://localhost:8081/actuator/端点url。如查看当前JVM内存占用情况,直接访问http://localhost:8081/actuator/metrics/jvm.memory.used
4、自定义端点Endpoint
除了Actuator自带的端点以外,我们还可以自定义所需要的端点。自定义端点需要先了解以下几个注解:
- @Component:注册为一个Spring Bean。
- @Endpoint:声明端点的注解,需要指定id=""属性,标识端点名称。
- @ReadOperation:用于定义读操作,允许获取关于应用程序状态的信息。它对应 HTTP 请求的 GET 方法。通常用于返回只读信息,例如获取应用程序的状态、性能指标等。
- @WriteOperation:用于定义写操作,允许进行应用程序的修改。它对应 HTTP 请求的 POST 方法。通常用于执行会修改应用程序状态的操作,例如重新加载配置、清理缓存等。
- @DeleteOperation:用于定义删除操作,允许进行资源的删除。它对应 HTTP 请求的 DELETE 方法。通常用于执行删除资源的操作,例如关闭数据库连接池、停止某个服务等。
- @Selector:用于@ReadOperation、@WriteOperation、@DeleteOperation标注的 Endpoint 方法时允许传递一些参数。
简单demo:
package com.example.springbootactuator.entpoint;import org.springframework.boot.actuate.endpoint.annotation.*;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;import java.util.HashMap;
import java.util.Map;/*** 注意:这里定义的端点名称只能是英文字母+数字,不能有其他字符,甚至下划线也不行。不然会提示 Value must only contain valid chars*/
@Component
@Endpoint(id = "myendpoint", enableByDefault = true)
public class MyEndpoint {@ReadOperationpublic Map<String, Object> endpointMyRead(@Selector String content) {Map<String, Object> customMap = new HashMap<>();customMap.put("httpMethod", HttpMethod.GET.toString());customMap.put("status", "200");customMap.put("content", content);return customMap;}@WriteOperationpublic Map<String, Object> endpointMyWrite() {Map<String, Object> customMap = new HashMap<>();customMap.put("httpMethod", HttpMethod.POST.toString());return customMap;}@DeleteOperationpublic Map<String, Object> endpointMyDelete() {Map<String, Object> customMap = new HashMap<>();customMap.put("httpMethod", HttpMethod.DELETE.toString());return customMap;}
}
运行后查看端点,可以看到多了我们自定义的myendpoint端点名称,同时多了一个可以接收{content}的端点连接,这个就是我们加了@Selector注解,允许接收参数。
来尝试访问下:http://localhost:8081/actuator/myendpoint/hello123123123。可以得到我们返回的map结构。
5、自定义health
我们还可以自定义health,用来检测其健康状态。这个也是我项目中用的比较多的,当时有一个需求是汇总所有的API请求,检测对方的API健康状态,并告警提醒,就是自定义了health。
要自定义health,可以自定义 HealthIndicator 来添加自定义的健康检查项。HealthIndicator 接口定义了一个 health() 方法,该方法返回一个 Health 对象,其中包含了应用程序的健康信息。也可以通过继承AbstractHealthIndicator抽象类来实现。
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.stereotype.Component;@Component
public class CustomHealthIndicator implements HealthIndicator {@Overridepublic Health health() {// 实现自定义的健康检查逻辑boolean isHealthy = checkHealth(); // 替换为实际的健康检查逻辑if (isHealthy) {return Health.up().withDetail("message", "Application is healthy").build();} else {return Health.down().withDetail("message", "Application is not healthy").build();}}private boolean checkHealth() {// 实际的健康检查逻辑,例如检查数据库连接、第三方服务状态等// 返回 true 表示健康,返回 false 表示不健康// 这里简单返回 true,实际应用中需要根据业务逻辑进行判断return true;}
}
运行程序,访问http://localhost:8081/actuator/health:
此外,可以添加以下配置,来查看health的详细信息:
management:endpoint:health:show-details: always
6、附录
贴出之前我对第三方API地址进行拨测的,实现health方式来检测健康状态的部分关键代码:
ThirdPartApiManager.java
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Table;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;/*** 第三方api地址管理器,统一管理API地址,不要直接在业务代码写死* 这里管理的api地址会进行状态监控*/
@Configuration
public class ThirdPartApiManager {@AutowiredThirdPartApiIpConfig thirdPartApiIpConfig;public static final Table<String, String, Long> THIRD_PART_API_TABLE = HashBasedTable.create();/*** 每次api心跳间隔,默认10分钟*/public static final Long INTERVAL_MICO_SECONDS = 10 * 60L * 1000;@SuppressWarnings("java:S125")public void thirdPartApiAdd() {//THIRD_PART_API_TABLE.put("获取客户信息", "http://localhost:8080/xxxxx", 1 * 60L * 1000);}}
ThirdPartApiManagerMonitor.java:
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointProperties;
import org.springframework.boot.actuate.autoconfigure.health.HealthIndicatorAutoConfiguration;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;/*** 第三方api地址心跳拨测* 拨测方式:对http发起options预请求,来诊断该接口的可用性* 注意:这里不发送trace方法,原因是trace可能会被黑客攻击,所以大多数系统trace是关闭的。*/
@Component
@Configuration
@AutoConfigureBefore({HealthIndicatorAutoConfiguration.class})
@EnableConfigurationProperties(HealthEndpointProperties.class)
@Slf4j
@Profile({"prod"})
public class ThirdPartApiManagerMonitor implements SchedulingConfigurer {@AutowiredConfigurableApplicationContext context;@AutowiredThirdPartApiManager thirdPartApiManager;@Beanpublic Map<String, Health> apiHealthResultMap() {return new ConcurrentHashMap<>(ThirdPartApiManager.THIRD_PART_API_TABLE.columnKeySet().size());}Function<ThirdPartApiDto, Health> healthIndicatorFunction = apiDto -> {Health.Builder healthBuilder = new Health.Builder().status(String.valueOf(apiDto.getStatus())).withDetail("httpCode", apiDto.getStatus()).withDetail("name", apiDto.getName()).withDetail("url", apiDto.getApi()).withDetail("description", apiDto.getName());/*** 状态码说明:* 100-199 用于指定客户端应相应的某些动作。* 200-299 用于表示请求成功。* 300-399 用于已经移动的文件并且常被包含在定位头信息中指定新的地址信息。* 400-499 用于指出客户端的错误。* 500-599 用于支持服务器错误。*/if (apiDto.getStatus() >= 400) {// 推送提醒......sendLarkMessage(apiDto);return healthBuilder.down().build();}return healthBuilder.up().build();};public int tryConnect(String url) {try {URL urlObj = new URL(url);HttpURLConnection connect = (HttpURLConnection) urlObj.openConnection();connect.setUseCaches(false);connect.setRequestMethod("OPTIONS");connect.setConnectTimeout(5000);return connect.getResponseCode();} catch (IOException e) {// nopreturn 500;}}@PostConstructpublic void registerApiHealth() {thirdPartApiManager.thirdPartApiAdd();ThirdPartApiManager.THIRD_PART_API_TABLE.columnKeySet().forEach(api -> {Optional<String> first = ThirdPartApiManager.THIRD_PART_API_TABLE.column(api).keySet().stream().findFirst();if (!first.isPresent()) {return;}context.getBeanFactory().registerSingleton(first.get() + "HealthIndicator", (HealthIndicator) () -> {if (apiHealthResultMap().containsKey(first.get())) {return apiHealthResultMap().get(first.get());}int status = tryConnect(api);ThirdPartApiDto thirdPartApiDto = ThirdPartApiDto.builder().name(first.get()).api(api).interval(ThirdPartApiManager.THIRD_PART_API_TABLE.column(api).getOrDefault(first.get(), ThirdPartApiManager.INTERVAL_MICO_SECONDS)).status(status).result(JSONUtil.toJsonStr(status)).createTime(DateUtil.now()).build();return healthIndicatorFunction.apply(thirdPartApiDto);});});}/*** 按照配置api,定时监控外部http状态*/@Overridepublic void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {ThirdPartApiManager.THIRD_PART_API_TABLE.columnKeySet().forEach(api -> {Optional<String> first = ThirdPartApiManager.THIRD_PART_API_TABLE.column(api).keySet().stream().findFirst();if (!first.isPresent()) {return;}LOGGER.info("拨测接口:{}, 地址:{}", first.get(), api);scheduledTaskRegistrar.addFixedRateTask(() -> {int status = tryConnect(api);ThirdPartApiDto thirdPartApiDto = ThirdPartApiDto.builder().name(first.get()).api(api).interval(ThirdPartApiManager.THIRD_PART_API_TABLE.column(api).getOrDefault(first.get(), ThirdPartApiManager.INTERVAL_MICO_SECONDS)).status(status).result(JSONUtil.toJsonStr(status)).createTime(DateUtil.now()).build();apiHealthResultMap().put(first.get(), healthIndicatorFunction.apply(thirdPartApiDto));}, ThirdPartApiManager.THIRD_PART_API_TABLE.column(api).getOrDefault(first.get(), ThirdPartApiManager.INTERVAL_MICO_SECONDS));});}@Beanpublic HealthIndicator testHealthIndicator() {return () -> new Health.Builder().up().build();}public void sendLarkMessage(ThirdPartApiDto thirdPartApiDto) {// ...}
}
7、小结
Spring Actuator在实际项目中使用还是很广泛的,根据项目实际情况适当扩展或自定义各个端点,提供更契合场景的度量指标,对项目会有很大的帮助。
相关文章:

05. Springboot admin集成Actuator(一)
目录 1、前言 2、Actuator监控端点 2.1、健康检查 2.2、信息端点 2.3、环境信息 2.4、度量指标 2.5、日志文件查看 2.6、追踪信息 2.7、Beans信息 2.8、Mappings信息 3、快速使用 2.1、添加依赖 2.2、添加配置文件 2.3、启动程序 4、自定义端点Endpoint 5、自定…...

AI生成SolidUI-新版本架构调试Debug
背景 SolidUI 0.5.0 版本重构全新版本架构。 dev-python 新架构临时分支,架构调整完后,所有代码合并到dev分支 https://github.com/CloudOrc/SolidUI 使用 设置参数 FLASK_DEBUG 设置 在开发过程中,Web框架的服务器通常会监视代码的变…...

ctfshow sql 195-200
195 堆叠注入 十六进制 if(preg_match(/ |\*|\x09|\x0a|\x0b|\x0c|\x0d|\xa0|\x00|\#|\x23|\|\"|select|union|or|and|\x26|\x7c|file|into/i, $username)){$ret[msg]用户名非法;die(json_encode($ret));}可以看到没被过滤,select 空格 被过滤了,可…...
微信小程序实现地图功能(腾讯地图)
微信小程序实现地图功能(腾讯地图) 主要功能 通过微信 API 获取用户当前位置信息 使用腾讯地图 API 将经纬度转换为地址信息 显示当前位置信息以及周围的 POI(兴趣点) 代码实现 index.wxml <!-- index.wxml --> <view class"container&…...

Vue如何请求接口——axios请求
1、安装axios 在cmd或powershell打开文件后,输入下面的命令 npm install axios 可在项目框架中的package.json中查看是否: 二、引用axios import axios from axios 在需要使用的页面中引用 三、get方式使用 get请求使用params传参,本文只列举常用参数…...

【数据结构一】初始Java集合框架(前置知识)
Java中的数据结构 Java语言在设计之初有一个非常重要的理念便是:write once,run anywhere!所以Java中的数据结构是已经被设计者封装好的了,我们只需要实例化出想使用的对象,便可以操作相应的数据结构了,本篇…...
直接将第三方数据插入到 Redis 中
Redis 是一个内存数据库,可以用于缓存和持久化数据。虽然常见的使用场景是将数据从关系型数据库(如MySQL)同步到 Redis 中进行缓存,但也可以直接将第三方数据插入到 Redis 中。 你可以通过编程语言的 Redis 客户端库(…...
【重点】【DP】322.零钱兑换
题目 法1:动态规划 // 时间复杂度:O(kN) class Solution {public int coinChange(int[] coins, int amount) {int[] dp new int[amount 1];Arrays.fill(dp, amount 1);dp[0] 0;for (int i 1; i < dp.length; i) {for (int coin : coins) {if (…...

Python入门学习篇(六)——for循环while循环
1 for循环 1.1 常规for循环 1.1.1 语法结构 for 变量名 in 可迭代对象:# 遍历对象时执行的代码 else:# 当for循环全部正常运行完(没有报错和执行break)后执行的代码1.1.2 示例代码 print("----->学生检查系统<------") student_lists["张三",&qu…...

el-table 实现行拖拽排序
element ui 表格实现拖拽排序的功能,可以借助第三方插件Sortablejs来实现。 引入sortablejs npm install sortablejs --save组件中使用 import Sortable from sortablejs;<el-table ref"el-table":data"listData" row-key"id" …...

2. 结构型模式 - 桥接模式
亦称: Bridge 意图 桥接模式是一种结构型设计模式, 可将一个大类或一系列紧密相关的类拆分为抽象和实现两个独立的层次结构, 从而能在开发时分别使用 问题 抽象? 实现? 听上去挺吓人? 让我们慢慢来&#x…...

最小二乘法简介
最小二乘法简介 1、背景描述2、最小二乘法2.1、最小二乘准则2.2、最小二乘法 3、最小二乘法与线性回归3.1、最小二乘法与线性回归3.2、最小二乘法与最大似然估计 4、正态分布(高斯分布) 1、背景描述 在工程应用中,我们通常会用一组观测数据去…...

mathtype公式章节编号
1. word每章标题后插入章节符 如果插入后显示章节符,需要进行隐藏 开始->样式->MTEquationSection->修改样式->字体,勾选隐藏 2. 设置mathtype公式编号格式 插入编号->格式化->设置格式...

医学实验室检验科LIS信息系统源码
实验室信息管理是专为医院检验科设计的一套实验室信息管理系统,能将实验仪器与计算机组成网络,使病人样品登录、实验数据存取、报告审核、打印分发,实验数据统计分析等繁杂的操作过程实现了智能化、自动化和规范化管理。 实验室管理系统功能介…...

无需改动现有网络,企业高速远程访问内网Linux服务器
某企业为数据治理工具盒厂商,帮助客户摆脱数据问题困扰、轻松使用数据,使得客户可以把更多精力投入至数据应用及业务赋能,让数据充分发挥其作为生产要素的作用。 目前,该企业在北京、南京、西安、武汉等地均设有产研中心ÿ…...

Opencv入门五 (显示图片灰度值)
源码如下: #include <opencv2/opencv.hpp> int main(int argc, char** argv) { cv::Mat img_rgb, img_gry, img_cny; cv::namedWindow("Example Gray",cv::WINDOW_AUTOSIZE); cv::namedWindow("Example Canny", cv::WINDOW_…...

STM32F4 HAL流水灯Proteus仿真
源码下载:https://download.csdn.net/download/zlkk00/88654405...

【K8s】4# 使用kuboard部署开源项目实战
文章目录 1.开源项目2.实战2.1.创建spring-blade命名空间2.2.导入 spring-blade 到 K8S 名称空间2.3.设置存储卷参数2.4.调整节点端口2.5.确认导入2.6.查看集群2.7.导入配置到 nacos2.8.启动微服务工作负载 3.验证部署结果3.1.Nacos3.2. web 4.问题汇总Q1:Nacos启动…...

Mysql数据库(1)
目录 一.操作系统 二.数据库mysql 对象: 库 -> 表 -> 二维表格形式的结构化数据 常用的数据类型: MySQL的六大约束属性: SQL语句 :DDL DML DQL DCL 三.mysql的基础操作 查看当前服务器中的数据库 查看当前服务器中…...

网络安全-API接口安全
本文为作者学习文章,按作者习惯写成,如有错误或需要追加内容请留言(不喜勿喷) 本文为追加文章,后期慢慢追加 API接口概念 API接口(Application Programming Interface,应用程序编程接口&…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...
反射获取方法和属性
Java反射获取方法 在Java中,反射(Reflection)是一种强大的机制,允许程序在运行时访问和操作类的内部属性和方法。通过反射,可以动态地创建对象、调用方法、改变属性值,这在很多Java框架中如Spring和Hiberna…...

Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...

人机融合智能 | “人智交互”跨学科新领域
本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...

2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)
安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...

FFmpeg:Windows系统小白安装及其使用
一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】,注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录(即exe所在文件夹)加入系统变量…...

给网站添加live2d看板娘
给网站添加live2d看板娘 参考文献: stevenjoezhang/live2d-widget: 把萌萌哒的看板娘抱回家 (ノ≧∇≦)ノ | Live2D widget for web platformEikanya/Live2d-model: Live2d model collectionzenghongtu/live2d-model-assets 前言 网站环境如下,文章也主…...

解析奥地利 XARION激光超声检测系统:无膜光学麦克风 + 无耦合剂的技术协同优势及多元应用
在工业制造领域,无损检测(NDT)的精度与效率直接影响产品质量与生产安全。奥地利 XARION开发的激光超声精密检测系统,以非接触式光学麦克风技术为核心,打破传统检测瓶颈,为半导体、航空航天、汽车制造等行业提供了高灵敏…...