资讯详情

Spring Boot Actuator 深度解析:从探针原理到生产级监控实践

📅 2026/10/17 10:30:33 | 华诺云谱 👁 阅读
Spring Boot Actuator 深度解析:从探针原理到生产级监控实践
1. 这不是“加个依赖就能用”的功能而是生产环境的呼吸监测仪很多人第一次接触 Spring Boot Actuator是在某次面试被问到“怎么查看应用健康状态”时脱口而出“加个 spring-boot-starter-actuator 依赖再配个 management.endpoints.web.exposure.include* 就行。”——话音未落面试官眼神已经飘向窗外。这就像说“给汽车装个仪表盘拧开油盖就能开车”完全忽略了仪表盘背后连接着发动机传感器、CAN总线、ECU诊断协议以及驾驶员真正需要判断的是“水温是否在90℃±5℃稳定运行”而不是“冷却液温度传感器电压值2.37V”。Actuator 的本质是 Spring Boot 为应用注入的一套可编程的运行时探针系统。它不生产监控数据而是把 JVM 内存堆栈、线程池状态、HTTP 路由映射、数据库连接池活跃数、甚至自定义业务指标比如“过去5分钟订单创建失败率”这些原本散落在日志、JVM 参数、数据库命令里的碎片信息统一抽象成标准 HTTP 端点或 JMX MBean。它的价值从来不在“能看”而在于“看得准、看得稳、看得懂、看得及时”。我曾在某电商大促前夜参与一个核心结算服务的压测保障。当时所有团队都在盯着 Grafana 面板上的 QPS 和响应时间曲线但真正揪出瓶颈的是 Actuator 暴露的/actuator/threaddump端点里一份 3MB 的线程快照其中 47 个线程卡死在org.apache.http.impl.conn.PoolingHttpClientConnectionManager.closeExpiredConnections根源是 HTTP 客户端连接池的maxIdleTime配置为 0即永不清理空闲连接导致连接泄漏后耗尽资源。这个细节任何 APM 工具的默认大盘都不会主动标红提示——它只在你明确去查、且知道该查什么的时候才给出答案。所以本课不讲“如何启用 Actuator”而是带你亲手拆解这台“呼吸监测仪”的四个核心部件探针如何植入自动配置原理、数据如何生成指标采集链路、接口如何暴露安全与路由机制、以及最关键的——你该盯住哪几个端点、为什么是这几个、它们的返回值每一行到底在说什么。这不是配置教程这是解读应用生命体征的临床手册。提示本文所有实操均基于 Spring Boot 3.2.x当前最新稳定版其 Actuator 默认使用 Micrometer 1.12 作为指标抽象层与旧版 2.x 的spring-boot-starter-actuator在端点路径、安全模型、指标命名规范上存在实质性差异。若你项目仍在用 2.7.x请务必注意文末的兼容性对照说明。2. 探针的植入逻辑自动配置不是魔法而是条件装配的精密流水线当你在pom.xml中加入artifactIdspring-boot-starter-actuator/artifactId你实际引入的是一组精心编排的AutoConfiguration 类它们并非简单地“启动所有功能”而是像工厂流水线一样根据当前 classpath、JVM 环境、已声明的 Bean、甚至application.properties中的显式开关逐级判断哪些探针该激活、哪些该跳过。理解这条流水线是避免“配置了却看不到端点”或“端点返回 404”的前提。2.1 核心装配器EndpointAutoConfiguration是总控开关整个 Actuator 的启动入口是org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration。它本身不直接创建任何端点而是通过Import导入三类关键配置EndpointProperties将management.*开头的配置项如management.endpoints.web.exposure.include绑定为类型安全的 Java BeanEndpointIdConverterConfiguration注册EndpointId类型转换器确保 URL 路径/actuator/health能正确解析为EndpointId(health)WebEndpointAutoConfiguration/JmxEndpointAutoConfiguration分别负责 Web 端点和 JMX 端点的条件化装配。这个设计的关键在于所有端点的自动装配都以EndpointAutoConfiguration为父上下文共享同一套配置源和条件判断逻辑。这意味着如果你在application.yml中写了management.endpoints.web.exposure.include: health,info那么WebEndpointAutoConfiguration下的所有子配置类如HealthEndpointAutoConfiguration都会读取这个值并决定是否将HealthEndpoint注册为 Web 可访问端点。2.2 端点实例的诞生从Endpoint注解到ExposableWebEndpoint真正的端点功能由标注了Endpoint(id health)的类提供。以最基础的HealthEndpoint为例它的源码结构如下Endpoint(id health) public class HealthEndpoint implements SupplierHealth { private final HealthContributorRegistry registry; public HealthEndpoint(HealthContributorRegistry registry) { this.registry registry; } ReadOperation // 关键声明这是一个读取操作 public Health getHealth(Selector String name) { // Selector 支持路径参数如 /actuator/health/db return this.registry.getContributor(name).getHealth(); } }这里有两个极易被忽略的细节ReadOperation不是装饰而是契约Actuator 的 Web 暴露层WebMvcEndpointHandlerMapping会扫描所有EndpointBean然后查找其方法上标注的ReadOperation、WriteOperation或DeleteOperation。只有带这些注解的方法才会被映射为 HTTP 接口。如果你自己写了一个Endpoint类却忘了加ReadOperation那么无论配置如何该端点在 Web 层永远不可见。HealthContributorRegistry是动态插槽HealthEndpoint本身不硬编码检查数据库、Redis 或 Kafka 的逻辑它只负责调用registry.getContributor(name)。而HealthContributor的具体实现如DataSourceHealthIndicator、RedisReactiveHealthIndicator则由各自的 starterspring-boot-starter-jdbc、spring-boot-starter-data-redis通过ConditionalOnClass自动注册。这就是为什么你加了spring-boot-starter-data-redis/actuator/health/redis端点就自动可用——它不是 Actuator “内置”的而是 Redis Starter “贡献”给 HealthRegistry 的。2.3 条件装配的实战陷阱为什么你的/actuator/metrics返回 404最常见的困惑是“我明明加了 actuator 依赖也配了exposure.include: metrics但访问/actuator/metrics却是 404”。根本原因往往出在Micrometer 的条件装配链上。MetricsEndpoint的自动配置类是MetricsEndpointAutoConfiguration它有一个关键条件ConditionalOnBean(MeterRegistry.class)而MeterRegistry的 Bean 是由MicrometerAutoConfiguration创建的其自身又依赖ConditionalOnClass({ MeterRegistry.class, AutoConfiguredCompositeMeterRegistry.class })这意味着仅引入spring-boot-starter-actuator并不足以启用 metrics 端点。你必须同时引入至少一个 Micrometer 的实现库例如!-- 启用 Prometheus 指标暴露 -- dependency groupIdio.micrometer/groupId artifactIdmicrometer-registry-prometheus/artifactId /dependency或者如果你只想在本地调试用最轻量的simple实现dependency groupIdio.micrometer/groupId artifactIdmicrometer-registry-simple/artifactId /dependency没有这个依赖MeterRegistryBean 根本不会被创建MetricsEndpointAutoConfiguration就会被 Spring Boot 的条件装配机制直接跳过MetricsEndpointBean 也就永远不会存在——自然无法映射到/actuator/metrics。注意Spring Boot 3.2 默认不再自动配置SimpleMeterRegistry。如果你没引入任何 registry 实现/actuator/metrics端点必然 404。这是与 2.x 版本的重大行为变更也是线上排查的第一怀疑点。3. 数据的生成真相指标不是“被采集的”而是“被观测的”Actuator 的/actuator/metrics端点返回的是一份指标名称列表如jvm.memory.used,http.server.requests而/actuator/metrics/{name}如/actuator/metrics/jvm.memory.used则返回该指标的具体测量值。很多人误以为这些数值是 Actuator “定时轮询 JVM 或 Tomcat 得到的”这是对 Micrometer 架构的根本性误解。3.1 Micrometer 的核心范式观测者模式Observer PatternMicrometer 的设计哲学是“Instrumentation First, Collection Later”先埋点后收集。它不主动拉取数据而是要求你在代码中主动声明“这里有一个值得观测的量”。例如// 在某个 Service 类中 Component public class OrderService { private final Counter orderCreatedCounter; // 声明一个计数器 public OrderService(MeterRegistry registry) { // 在构造器中注册计数器指定指标名和标签 this.orderCreatedCounter Counter.builder(order.created) .description(Total number of orders created) .tag(status, success) .register(registry); } public void createOrder(Order order) { // 业务逻辑... this.orderCreatedCounter.increment(); // 每次成功创建计数器1 } }这段代码执行后/actuator/metrics/order.created就会返回该计数器的累计值。关键在于increment()调用发生在业务代码执行时而非 Actuator 启动时。Micrometer 的MeterRegistry只是一个内存中的注册中心它保存着所有Counter、Timer、Gauge等指标对象的引用。当/actuator/metrics/order.created被请求时Actuator 的MetricsEndpoint只是调用registry.find(order.created).counter().count()直接读取内存中该Counter对象的当前值。3.2 Spring Boot 的自动埋点那些你没写的Timed和Counted手动写Counter.builder(...).register(registry)很繁琐。Spring Boot 通过micrometer-core的Timed、Counted、Gauge等注解实现了面向切面的自动埋点。例如Service public class PaymentService { Timed(value payment.process.time, histogram true, // 启用直方图用于计算 P95/P99 extraTags {method, creditCard}) public void processPayment(Payment payment) { // 处理支付逻辑... } Counted(value payment.attempt, description Number of payment attempts) public void attemptPayment(Payment payment) { // 尝试支付... } }这些注解生效的前提是项目中必须存在EnableAspectJAutoProxySpring Boot 默认开启和MeterRegistryBean。Spring Boot 的TimedAspect和CountedAspect会扫描所有被注解的方法在方法执行前后自动调用Timer.record()或Counter.increment()。但请注意Timed默认只记录总耗时sum和调用次数count不记录分布histogram。要获取 P95/P99 延迟必须显式设置histogram true否则/actuator/metrics/payment.process.time返回的percentiles字段永远为空。3.3 JVM 底层指标的来源不是 Actuator “读取”而是 JVM “推送”像jvm.memory.used、jvm.threads.live这类指标看起来像是 Actuator 直接读取 JVM MBean。实际上Micrometer 的JvmMemoryMetrics、JvmThreadMetrics等类是在应用启动时通过ManagementFactory.getMemoryMXBean()等标准 JMX API 获取 JVM 管理 Bean 的引用并注册一个ScheduledExecutorService以固定间隔默认 1 分钟调用getUsage().getUsed()等方法将结果更新到对应的Gauge对象中。这意味着jvm.memory.used的值是 Micrometer 主动“拉取”并缓存的结果而非实时反射。它的更新频率由management.metrics.export.simple.step默认 60s控制。如果你需要秒级精度可以将其调小但需权衡 CPU 开销。实操心得在压测环境中将management.metrics.export.simple.step设为10s配合/actuator/metrics/jvm.memory.used的高频轮询能比 GC 日志更早发现内存泄漏趋势。但切记不要设为1s——过于频繁的 JMX 调用本身就会成为性能瓶颈。4. 端点的安全与暴露暴露/actuator/env是在敞开应用的保险柜Actuator 的端点按敏感度分为两类非敏感端点如/health,/info和敏感端点如/env,/beans,/loggers,/threaddump。Spring Boot 3.2 的默认策略是所有端点默认关闭 Web 暴露必须显式声明才可访问。这与 2.x 的“默认暴露 health/info其余需手动开启”有本质区别。4.1 暴露策略的三层控制模型Actuator 的暴露控制是三层嵌套的控制层级配置项作用范围默认值全局开关management.endpoints.enabled-by-default控制所有端点Web JMX是否默认启用trueWeb 层开关management.endpoint.id.show-details控制单个端点在 Web 层的详细程度never,when_authorized,alwaysnever暴露白名单management.endpoints.web.exposure.include控制哪些端点 ID 允许通过 Web 访问health,info这三个配置的关系是一个端点要能被 Web 访问必须同时满足1enabled-by-defaulttrue2其 ID 在exposure.include列表中3show-details允许显示内容。例如要让/actuator/env可访问你需要management: endpoints: enabled-by-default: true # 确保 env 端点本身是启用的 endpoint: env: show-details: when_authorized # 仅对认证用户显示详情 endpoints: web: exposure: include: health,info,env # 显式加入 env4.2/actuator/env的致命风险它不只是“看配置”而是“看所有”/actuator/env端点返回的是 SpringEnvironment接口的完整快照包含所有application.yml/application.properties中的属性系统环境变量PATH,JAVA_HOMEJVM 启动参数-Dserver.port8080最关键的是所有ConfigurationProperties绑定的 Bean 的当前值包括密码、密钥、数据库 URL。曾有一个真实案例某公司运维人员为快速排查问题在测试环境将management.endpoints.web.exposure.include: *并忘记加认证。安全扫描工具在 3 小时后就捕获到/actuator/env返回的spring.datasource.password字段该密码与生产数据库主账号完全一致。漏洞评级为Critical。因此我的硬性建议是永远不要在任何环境包括本地开发中使用exposure.include: */env端点只应在有严格 IP 白名单 Basic Auth 的内部运维网络中开放如果只是想查看某个配置项用/actuator/configprops只返回ConfigurationPropertiesBean 的结构化信息不包含原始值或/actuator/conditions只返回自动配置的匹配/不匹配原因替代。4.3 生产环境的最小暴露清单一份经过千次压测验证的配置基于多个高并发金融、电商项目的实战经验我推荐的生产环境application-prod.ymlActuator 配置如下management: endpoints: enabled-by-default: false # 关闭所有端点默认启用 endpoint: health: show-details: when_authorized # 健康检查详情需授权 probes: show-details: when_authorized metrics: show-details: never # metrics 本身不敏感但详情无意义 prometheus: show-details: never # 若使用 Prometheus此端点需单独暴露 endpoints: web: base-path: /actuator # 保持默认路径 exposure: include: health,metrics,prometheus,threaddump # 仅暴露必需端点 cors: allowed-origins: https://monitoring.internal.company.com # 严格 CORS server: port: 8081 # 独立管理端口与业务端口分离 endpoint: health: group: liveness: show-details: never # 存活探针只返回 status readiness: show-details: when_authorized # 就绪探针可查看依赖状态这份配置的核心逻辑是端口分离管理端口8081与业务端口8080物理隔离防火墙可直接封禁8081对外网的访问最小集暴露health存活/就绪、metrics供 Prometheus 抓取、prometheus原生格式、threaddump紧急诊断threaddump的特殊处理它不返回敏感业务数据但能暴露线程栈中的方法名和参数可能含订单号等 ID故必须when_authorizedliveness/readiness分组Kubernetes 健康检查应分别调用/actuator/health/liveness和/actuator/health/readiness前者极简毫秒级响应后者可包含数据库连接检查允许秒级超时。提示/actuator/health/readiness的响应时间应是你整个服务中最慢的依赖如数据库的连接超时时间 200ms。如果数据库connectTimeout3000ms那么 readiness 端点的timeout必须设为3200ms否则 K8s 会因超时反复重启 Pod。5. 真正的监控闭环从/actuator/health的 JSON 到告警规则的落地Actuator 最常被滥用的端点就是/actuator/health。很多人把它当成“应用是否活着”的二值开关却忽略了它是一个可深度定制的健康状态决策引擎。5.1HealthIndicator的分级响应UP/DOWN只是表象/actuator/health的默认返回是{ status: UP, components: { diskSpace: { status: UP, details: { total: 500... } }, ping: { status: UP } } }这里的status: UP是由HealthAggregator计算得出的聚合结果。Spring Boot 提供两种聚合策略OrderedHealthAggregator默认按Health对象的status排序DOWNOUT_OF_SERVICEUPUNKNOWN取最高级别状态作为整体statusSimpleHealthAggregator只要有一个DOWN整体就是DOWN。但更重要的是你可以为每个HealthIndicator设置不同的status映射规则。例如数据库连接池的健康检查DataSourceHealthIndicator默认只检查连接是否能建立。但你可以重写它使其在连接池活跃连接数 95% 时返回Status.OUT_OF_SERVICEComponent public class CustomDataSourceHealthIndicator extends DataSourceHealthIndicator { private final HikariDataSource dataSource; public CustomDataSourceHealthIndicator(HikariDataSource dataSource) { super(dataSource); this.dataSource dataSource; } Override protected void doHealthCheck(Builder builder) throws Exception { super.doHealthCheck(builder); // 先执行默认检查连接是否通 // 额外检查连接池使用率 int active dataSource.getHikariPoolMXBean().getActiveConnections(); int max dataSource.getMaximumPoolSize(); double usageRate (double) active / max; if (usageRate 0.95) { builder.status(Status.OUT_OF_SERVICE) .detail(connectionPoolUsageRate, usageRate); } } }这样当/actuator/health返回{ status: OUT_OF_SERVICE, components: { dataSource: { status: OUT_OF_SERVICE, details: { connectionPoolUsageRate: 0.97 } } } }Kubernetes 的readinessProbe就会将该 Pod 从 Service 的 Endpoint 列表中移除流量不再打入从而避免雪崩。5.2 告警规则的黄金三原则从 JSON 字段到 Prometheus Rule要将 Actuator 的 JSON 数据转化为有效的告警必须遵循三个铁律字段必须可预测告警规则不能依赖details中的任意字段因为不同HealthIndicator的details结构千差万别。唯一稳定的是status字符串和components.id.status。状态必须可聚合/actuator/health是一个整体端点无法对单个组件如db单独抓取。因此必须使用/actuator/health/component子端点如/actuator/health/db来获取独立状态。HTTP 状态码必须参与判断/actuator/health/db在数据库连通时返回200 OK不通时返回503 Service Unavailable。Prometheus 的probe_http_status_code指标天然支持此判断。基于此一个生产级的数据库健康告警规则应为# Prometheus rules.yml - alert: DatabaseUnhealthy expr: probe_http_status_code{jobactuator-health-db} ! 200 for: 2m labels: severity: critical annotations: summary: Database health check failed description: The /actuator/health/db endpoint returned {{ $value }} instead of 200 - alert: DatabaseHighConnectionUsage expr: (probe_http_duration_seconds{jobactuator-health-db} * 1000) 2000 for: 5m labels: severity: warning annotations: summary: Database health check latency high description: Database health check took {{ $value }}ms, indicating potential connection pool exhaustion这里的关键是第一个告警看 HTTP 状态码503第二个告警看 HTTP 延迟2s。前者是“是否连得上”后者是“连得有多勉强”。两者结合才能覆盖数据库故障的全场景。5.3 一次真实的故障复盘/actuator/health如何提前 17 分钟预警去年双十一大促期间某支付网关的/actuator/health端点在 21:43:12 突然从UP变为OUT_OF_SERVICE但业务接口POST /pay仍能正常返回200。SRE 团队立即收到告警登录服务器执行curl -s http://localhost:8081/actuator/health | jq .components.redis.status # 返回 DOWN进一步检查/actuator/health/redis{ status: DOWN, details: { error: org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis; nested exception is io.lettuce.core.RedisConnectionException: Unable to connect to localhost:6379 } }此时Redis 服务其实尚未完全宕机只是主从同步出现网络分区从节点无法连接主节点。而支付业务的RedisTemplate配置了readFrom ReadFrom.REPLICA_PREFERRED所以读请求仍能走从节点业务未中断。但RedisHealthIndicator的默认检查是ping()主节点因此率先暴露了问题。SRE 团队在 21:43:25 切换 Redis 连接配置为readFrom ReadFrom.MASTER并在 21:43:42 通过/actuator/refresh热刷新配置。整个过程耗时 30 秒而业务完全无感。17 分钟后Redis 主节点彻底崩溃所有未切换的下游服务开始报错——而我们的网关早已平稳运行。这个案例印证了一个朴素真理Actuator 不是故障发生后的“验尸报告”而是故障发生前的“心电监护仪”。它的价值永远在于那几秒钟的提前量。6. 从入门到精通五个必须掌握的自定义端点实战模板Actuator 的终极价值不在于它预置的十几个端点而在于它为你提供的标准化端点开发框架。以下是我总结的五种最高频、最实用的自定义端点模式每一种都附有可直接复制的代码和部署要点。6.1 模式一业务状态快照端点/actuator/business-status适用场景需要向运维/监控系统暴露业务核心状态如“当前库存同步任务是否在运行”、“风控规则版本号”、“最近一次对账完成时间”。Component Endpoint(id business-status) // 端点ID对应URL /actuator/business-status public class BusinessStatusEndpoint { private final InventorySyncService syncService; private final RiskRuleService ruleService; private final ReconciliationService reconService; public BusinessStatusEndpoint(InventorySyncService syncService, RiskRuleService ruleService, ReconciliationService reconService) { this.syncService syncService; this.ruleService ruleService; this.reconService reconService; } ReadOperation // 必须标注否则Web层不可见 public MapString, Object getStatus() { MapString, Object status new HashMap(); status.put(inventorySyncRunning, syncService.isRunning()); status.put(riskRuleVersion, ruleService.getCurrentVersion()); status.put(lastReconciliationTime, reconService.getLastSuccessTime()); status.put(reconciliationStatus, reconService.getLastStatus()); return status; } }部署要点在application.yml中添加management.endpoints.web.exposure.include: health,info,business-status此端点无需WriteOperation纯读取安全风险低返回的Map会自动序列化为 JSON字段名即为 key。6.2 模式二动态配置热更新端点/actuator/config-reload适用场景避免每次修改配置都要重启应用尤其适用于灰度发布时的参数微调如限流阈值、降级开关。Component Endpoint(id config-reload) public class ConfigReloadEndpoint { private final ConfigurableEnvironment environment; private final ApplicationContext context; public ConfigRefreshEndpoint(ConfigurableEnvironment environment, ApplicationContext context) { this.environment environment; this.context context; } WriteOperation // 注意这是写操作需严格权限控制 public String reloadConfig(Selector String source) { try { // 1. 从外部源如Consul、Nacos拉取最新配置 Properties props fetchLatestConfig(source); // 2. 创建新的 PropertySource 并添加到 Environment MutablePropertySources propertySources environment.getPropertySources(); propertySources.addFirst(new PropertiesPropertySource(dynamic- source, props)); // 3. 触发 Context Refresh可选仅当Bean依赖Value注入时需要 ((ConfigurableApplicationContext) context).refresh(); return Config reloaded from source , total sources: propertySources.size(); } catch (Exception e) { throw new RuntimeException(Failed to reload config from source, e); } } private Properties fetchLatestConfig(String source) { // 实现从 Consul/Nacos 拉取配置的逻辑 return new Properties(); } }部署要点此端点必须设置show-details: when_authorized且仅对运维账号开放WriteOperation方法的参数Selector String source会从 URL 路径/actuator/config-reload/consul中提取consulcontext.refresh()是重量级操作会重建所有单例 Bean慎用大多数场景下只需更新Environment即可ConfigurationPropertiesBean 会自动监听变化。6.3 模式三诊断性线程分析端点/actuator/thread-analysis适用场景/actuator/threaddump返回的是原始 jstack 文本难以快速定位问题。此端点可自动分析并返回高亮结论。Component Endpoint(id thread-analysis) public class ThreadAnalysisEndpoint { ReadOperation public MapString, Object analyzeThreads() { ThreadMXBean threadBean ManagementFactory.getThreadMXBean(); long[] threadIds threadBean.getAllThreadIds(); ThreadInfo[] threadInfos threadBean.getThreadInfo(threadIds, 20); // 获取最多20帧栈 MapString, Object result new HashMap(); result.put(totalThreads, threadInfos.length); // 统计 BLOCKED/WAITING 线程数 long blockedCount Arrays.stream(threadInfos) .filter(ti - ti.getThreadState() Thread.State.BLOCKED) .count(); result.put(blockedThreads, blockedCount); // 查找持有锁最多的线程 String topLockHolder Arrays.stream(threadInfos) .filter(ti - ti.getLockOwnerId() ! -1) .max(Comparator.comparingLong(ti - ti.getLockedMonitors().length)) .map(ThreadInfo::getThreadName) .orElse(None); result.put(topLockHolder, topLockHolder); return result; } }部署要点此端点计算量小可放心暴露但show-details仍建议设为when_authorized返回的 JSON 包含可直接用于告警的数值如blockedThreads 50可与/actuator/threaddump配合使用先看分析结果再按需下载完整 dump。6.4 模式四指标导出端点/actuator/metrics-export适用场景某些老旧监控系统不支持 Prometheus 格式需要将 Micrometer 指标转为 CSV 或自定义 JSON。Component Endpoint(id metrics-export) public class MetricsExportEndpoint { private final MeterRegistry registry; public MetricsExportEndpoint(MeterRegistry registry) { this.registry registry; } ReadOperation public String exportAsCsv() { StringBuilder csv new StringBuilder(); csv.append(name,description,type,value,tags\n); registry.forEachMeter(meter - { String name meter.getId().getName(); String desc meter.getId().getDescription() ! null ? meter.getId().getDescription() : ; String type meter.getId().getType().toString(); // 获取指标值简化版实际需处理 Timer/Counter/Gauge 等不同类型 double value 0.0; if (meter instanceof Counter) { value ((Counter) meter).count(); } else if (meter instanceof Gauge) { value ((Gauge) meter).value(); } String tags meter.getId().getTags().stream() .map(tag - tag.getKey() tag.getValue()) .collect(Collectors.joining(;)); csv.append(String.format(\%s\,\%s\,\%s\,%.2f,\%s\\n, name, desc, type, value, tags)); }); return csv.toString(); } }部署要点此端点会遍历所有 Meter对高指标量10k的应用可能造成短暂 GC 压力建议设置ReadOperation的超时返回 CSV 可直接导入 Excel 或 Grafana 的 CSV 插件适合临时分析。6.5 模式五安全审计日志端点/actuator/audit-log适用场景记录所有对敏感端点如/actuator/env,/actuator/loggers的访问满足等保合规要求。Component Endpoint(id audit-log) public class AuditLogEndpoint { private final ListAuditRecord auditRecords Collections.synchronizedList(new ArrayList()); ReadOperation public ListAuditRecord getAuditLog( Selector(defaultValue 10) Integer limit, Selector(defaultValue DESC) String sort) { return auditRecords.stream() .sorted(sort.equals(ASC) ? Comparator.comparing(AuditRecord::getTimestamp) : Comparator.comparing(AuditRecord::getTimestamp).reversed()) .limit(limit) .collect(Collectors.toList()); } // 此方法由 Filter 或 Aspect 调用记录每次敏感端点访问 public void logAccess(String endpoint, String user, String
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑