Micrometer 系列【35】Spring Boot Micrometer Metrics 数据采集、指标查询解析
文章目录1. 前言2. 指标查询2.1 MetricsEndpointActuator 指标端点2.1.1 核心成员2.1.2 listNames()全量指标名称查询2.1.3 metric() 单指标详情查询2.2 全量指标名称查询接口2.3 指标详情接口3. 数据采集3.1 采集时触发3.2 内部状态维护3.2.1 自动配置3.2.2 请求开始3.2.3 请求结束3.2.4 查询数据1. 前言在之前的几篇文档中我们已经了解了在Micrometer原生框架中指标的整个生命周期包括实例化、注册、采集、销毁。原生MeterRegistry提供register、remove、close等底层API手动完成指标的增删与资源回收。那么在Spring Boot环境下一切不完全等同原生编码。Spring Boot自动装配、自动注入MeterRegistry、MeterBinder、自动构建内置指标、上下文生命周期钩子已经做到了开箱即用。通过之前Spring Boot Micrometer Metrics自动配置章节我们已经了解到根据classpath上的依赖创建对应的MeterRegistryBean整个Spring 应用只存在一个MeterRegistry实例。业务代码直接Autowired MeterRegistry registry注入使用。MeterBinder自动绑定内置指标Spring容器启动完成后收集全部MeterBinderBean并自动注册到全局registry。那么在Spring Boot场景中是如何实现数据采集、指标查询的呢2. 指标查询2.1 MetricsEndpointActuator 指标端点核心作用提供Spring Boot Actuator内置/actuator/metrics接口用于人工调试查看应用所有指标、实时数值、标签信息仅做只读查询不参与指标采集与生命周期管理。支持接口GET /actuator/metrics获取应用所有已注册指标名称列表GET /actuator/metrics/{metricName}?tagk1:v1根据指标名 标签过滤查询指标实时测量值、可用标签2.1.1 核心成员端点核心依赖MeterRegistrySpring Boot自动注入组合注册中心Endpoint(idmetrics)publicclassMetricsEndpoint{privatefinalMeterRegistryregistry;// ...}在引入了micrometer-registry-prometheus后注入的是PrometheusMeterRegistrycollectNames(names, this.registry)递归收集指标名privatevoidcollectNames(SetStringnames,MeterRegistryregistry){if(registryinstanceofCompositeMeterRegistrycompositeMeterRegistry){// 复合注册中心本身不存储meter遍历全部子registry递归调用compositeMeterRegistry.getRegistries().forEach((member)-collectNames(names,member));}else{// 真实底层registry(Prometheus/SimpleMeterRegistry)// getMeters() 获取meterMap全部meter快照registry.getMeters().stream().map(this::getName)// meter.getId().getName()只拿指标名字丢弃tag.forEach(names::add);}}2.1.2 listNames()全量指标名称查询核心逻辑递归遍历MeterRegistry所有指标器收集所有Meter的名称去重排序。关键特性仅读取指标元数据名称不执行measure()、不采集实时数值性能极高。ReadOperationpublicMetricNamesDescriptorlistNames(){SetStringnamesnewTreeSet();collectNames(names,this.registry);returnnewMetricNamesDescriptor(names);}2.1.3 metric() 单指标详情查询完整执行步骤解析标签参数parseTags()解析URLtagkey:value参数格式错误抛出参数异常匹配指标实例findFirstMatchingMeters()根据指标名标签匹配容器内注册的Meter空值处理无匹配指标直接返回nullHTTP响应404采集合并数值getSamples()调用meter.measure()获取测量数据合并多实例指标值过滤可用标签getAvailableTags()收集剩余可过滤标签移除 URL 已传入的过滤标签组装返回数据封装指标名、单位、测量值、可用标签等信息。ReadOperationpublicNullableMetricDescriptormetric(SelectorStringrequiredMetricName,NullableListStringtag){ListTagtagsparseTags(tag);CollectionMetermetersfindFirstMatchingMeters(this.registry,requiredMetricName,tags);if(meters.isEmpty()){returnnull;}MapStatistic,DoublesamplesgetSamples(meters);MapString,SetStringavailableTagsgetAvailableTags(meters);tags.forEach((t)-availableTags.remove(t.getKey()));Meter.IdmeterIdmeters.iterator().next().getId();returnnewMetricDescriptor(requiredMetricName,meterId.getDescription(),meterId.getBaseUnit(),asList(samples,Sample::new),asList(availableTags,AvailableTag::new));}解析tag参数parseTags(tag)将url的tagkey:value字符串列表转换MicrometerTag对象列表格式错误抛出异常。没有传tag返回空集合。findFirstMatchingMeters()在MeterRegistry查找匹配meterprivateCollectionMeterfindFirstMatchingMeters(MeterRegistryregistry,Stringname,IterableTagtags){if(registryinstanceofCompositeMeterRegistrycompositeMeterRegistry){returnfindFirstMatchingMeters(compositeMeterRegistry,name,tags);}returnregistry.find(name).tags(tags).meters();}getSamples()mergeMeasurements()采集并合并测量值meters.forEach((meter)-mergeMeasurements(samples,meter));meter.measure()// 实时执行采集返回一组Measurement{Statistic, value}合并规则Statistic.MAX取各个meter的最大值Double::max其余所有统计项执行求和Double::sum注意不是求平均值是sum/max合并。getAvailableTags()收集可用tag集合已经在url请求参数中指定的tag key从availableTags移除代表该维度已经被过滤不能再下钻。tags.forEach((t)-availableTags.remove(t.getKey()));最后组装MetricDescriptor DTO返回。2.2 全量指标名称查询接口需要开启暴露metrics端点management.endpoints.web.exposure.includemetrics访问路径GET /actuator/metrics请求参数无任何请求参数不需要path变量、不需要query参数。HTTP MethodGET对应注解ReadOperation只读操作。对比GET /actuator/metrics/{metricName}是另外一个方法metric()带Selector路径变量。响应DTOMetricNamesDescriptor implements OperationResponseBody响应示例{names:[application.ready.time,http.server.requests,jvm.memory.used,jvm.threads.live,system.cpu.usage]}2.3 指标详情接口访问路径GET /actuator/metrics/{metricName}请求参数路径变量参数说明metricName必填指标名称如jvm.memory.usedQuery参数参数说明示例tag可选可多次传用于按tag过滤meter格式必须key:valuetagstatus:200tagmethod:GET请求示例1不带tag过滤GET /actuator/metrics/jvm.memory.used请求示例2带tag过滤GET /actuator/metrics/http.server.requests?tagstatus:200tagmethod:GET返回DTOMetricDescriptor implements OperationResponseBody响应示例{name:jvm.memory.used,description:The amount of used memory,baseUnit:bytes,measurements:[{statistic:VALUE,value:186421344}],availableTags:[{tag:area,values:[heap,nonheap]}]}字段说明字段说明name指标名称入参传入的metricNamedescription指标描述来自MeterId可为nullbaseUnit基础单位(bytes/seconds等)可为nullmeasurements采集统计结果数组‑statistic统计类型VALUE/COUNT/TOTAL_TIME/MAX等‑value采集出来的数值实时调用meter.measure()得到availableTags还可以继续筛选的tag维度url上已经指定过的tag会被剔除‑tagtag key‑values该key下全部可选tag值集合3. 数据采集3.1 采集时触发我们以/actuator/metrics/jvm.memory.used为例MetricsEndpoint#findFirstMatchingMeters匹配到6个Gauge实例调用meter.measure()获取每个指标器中的所有度量值Measurement调用JDK Map原生merge方法如果key不存在直接put (key,value)如果key已经存在执行第三个参数的合并函数旧值、新值传入函数函数返回值作为新的value存入map。调用measurement.getValue()时触发真正采集指标数值samples.merge(measurement.getStatistic(),measurement.getValue()jvm.memory.used的Statistic类型是Value则会对所有Gauge实例的值进行求和返回进行标签过滤后直接返回响应对象使用Actuator内部的JSon序列化后返回到浏览器{availableTags:[{tag:area,values:[heap,nonheap]},{tag:id,values:[G1 Survivor Space,Compressed Class Space,Metaspace,CodeCache,G1 Old Gen,G1 Eden Space]}],baseUnit:bytes,description:The amount of used memory,measurements:[{statistic:VALUE,value:109319464}],name:jvm.memory.used}3.2 内部状态维护类型Timer计时器指标记录http服务请求耗时、请求次数。http.server.requests指标在Spring Boot 3.x以上的版本都基于Micrometer Observation模式进行统一观测了这里我们简单了解下。3.2.1 自动配置WebMvcObservationAutoConfiguration自动注册过滤器ServerHttpObservationFilter进行观测埋点。DefaultMeterObservationHandler把Observation事件转成Micrometer Meter指标3.2.2 请求开始执行时机HTTP请求进入过滤器业务逻辑尚未执行请求开始时执行DefaultMeterObservationHandler#onStart方法若开启shouldCreateLongTaskTimer获取/创建{name}.active的LongTaskTimer调用.start()得到采样对象将LongTaskTimer.Sample存入Observation.Context调用Timer.start(meterRegistry)生成Timer.Sample仅记录开始时间戳将Timer.Sample存入上下文OverridepublicvoidonStart(Observation.Contextcontext){if(shouldCreateLongTaskTimer){LongTaskTimer.SamplelongTaskSamplemeterRegistry.more().longTaskTimer(context.getName().active,createTags(context)).start();context.put(LongTaskTimer.Sample.class,longTaskSample);}Timer.SamplesampleTimer.start(meterRegistry);context.put(Timer.Sample.class,sample);}3.2.3 请求结束执行时机请求完成正常返回 / 异常请求完成时执行DefaultMeterObservationHandler#onStop方法从上下文提取、组装tags追加error标签获取上下文保存的Timer.SamplemeterRegistry.timer(context.getName(), tags)nametags不存在新建Timer Meter注册进meterMap已存在直接复用已有Timersample.stop(timer)计算耗时执行timer.record()写入耗时统计若开启长任务计时器取出LongTaskTimer.Sample执行.stop()结束活跃任务统计Override// TODO decide what to do about context.getName being NullableSuppressWarnings(NullAway)publicvoidonStop(Observation.Contextcontext){ListTagtagscreateTags(context);tags.add(Tag.of(error,getErrorValue(context)));Timer.Samplesamplecontext.getRequired(Timer.Sample.class);sample.stop(this.meterRegistry.timer(context.getName(),tags));if(shouldCreateLongTaskTimer){LongTaskTimer.SamplelongTaskSamplecontext.getRequired(LongTaskTimer.Sample.class);longTaskSample.stop();}}3.2.4 查询数据访问actuator/metrics/http.server.requests和【采集时触发】流程一致唯一的区别就是数据已经在内存中了。返回示例{availableTags:[{tag:exception,values:[none,IOException]},{tag:method,values:[GET]},{tag:error,values:[none,IOException]},{tag:uri,values:[/actuator/metrics/{requiredMetricName},/actuator/metrics,/actuator/prometheus]},{tag:outcome,values:[SUCCESS]},{tag:status,values:[200]}],baseUnit:seconds,measurements:[{statistic:COUNT,value:291},{statistic:TOTAL_TIME,value:8785.79363672},{statistic:MAX,value:714.0757704}],name:http.server.requests

相关新闻

GitHub Copilot 用户破 2000 万!AI 编程已不是「尝鲜」,掌握这 7 步让你的项目不再返工(收藏版)

GitHub Copilot 用户破 2000 万!AI 编程已不是「尝鲜」,掌握这 7 步让你的项目不再返工(收藏版)

GitHub Copilot 用户量激增,AI 工具普及但项目失败率居高不下。多数人仅将 AI 视为代码生成工具,忽略了项目成功的关键环节。文章提出 AI 辅助项目的 7 个核心环节:立项论证、需求定义、方案设计、辅助开发、测试验收、发布上线、运营迭代。强…

2026/8/10 18:49:52 阅读更多 →
Windows版本升级终极指南:如何免费实现版本自由切换的完整教程

Windows版本升级终极指南:如何免费实现版本自由切换的完整教程

Windows版本升级终极指南:如何免费实现版本自由切换的完整教程 【免费下载链接】In-Place_Upgrade_Helper Helper-Tool for Windows 10/11/Server In-Place-upgrades and changing between Windows Editions 项目地址: https://gitcode.com/GitHub_Trending/in/In…

2026/8/10 18:49:52 阅读更多 →
小白程序员必看:大模型检索与排序实战指南(收藏版)

小白程序员必看:大模型检索与排序实战指南(收藏版)

本文详细介绍了多轮Query改写、全文检索、向量检索、混合检索、排序算法以及基于LLM的相关性判断等大模型检索与排序的关键技术。内容涵盖了从基础概念到实际应用的多个方面,包括TFIDF、BM25、BERT、向量模型、RRF融合排序、Cross-Encoder、CoIBERT等,并…

2026/8/10 18:48:52 阅读更多 →

最新新闻

快速解决JXBanner常见问题:从数据刷新到动画异常排查

快速解决JXBanner常见问题:从数据刷新到动画异常排查

快速解决JXBanner常见问题:从数据刷新到动画异常排查 【免费下载链接】JXBanner 🚀🚀🚀 A super - custom multifunctional framework for banner unlimited rollover diagrams [一个超自定义多功能无限轮播图框架] 项目地址: h…

2026/8/10 19:35:08 阅读更多 →
DevOps Interview Guide中的边缘AI:边缘设备部署策略

DevOps Interview Guide中的边缘AI:边缘设备部署策略

DevOps Interview Guide中的边缘AI:边缘设备部署策略 【免费下载链接】DevOps-Interview-Guide DevOps Interview Guide 项目地址: https://gitcode.com/GitHub_Trending/de/DevOps-Interview-Guide 在当今数字化转型浪潮中,边缘AI正成为连接云端…

2026/8/10 19:35:08 阅读更多 →
计算机毕业设计之高校会议室预订管理系统

计算机毕业设计之高校会议室预订管理系统

伴随着我国社会的发展,人民生活质量日益提高。于是对系统进行规范而严格是十分有必要的,所以许许多多的信息管理系统应运而生。此时单靠人力应对这些事务就显得有些力不从心了。所以本论文将设计一套高校会议室预订管理系统,帮助学校进行会议…

2026/8/10 19:35:08 阅读更多 →
RDPWrap完全指南:5分钟解锁Windows远程桌面多用户连接限制

RDPWrap完全指南:5分钟解锁Windows远程桌面多用户连接限制

RDPWrap完全指南:5分钟解锁Windows远程桌面多用户连接限制 【免费下载链接】rdpwrap.ini RDPWrap.ini for RDP Wrapper Library by StasM 项目地址: https://gitcode.com/GitHub_Trending/rd/rdpwrap.ini 你是否曾经遇到这样的困扰:公司只有一台W…

2026/8/10 19:35:08 阅读更多 →
Three.quarks深度解析:高性能粒子系统架构设计与移动端优化方案

Three.quarks深度解析:高性能粒子系统架构设计与移动端优化方案

Three.quarks深度解析:高性能粒子系统架构设计与移动端优化方案 【免费下载链接】three.quarks Three.quarks is a general purpose particle system / VFX engine for three.js 项目地址: https://gitcode.com/GitHub_Trending/th/three.quarks Three.quark…

2026/8/10 19:35:08 阅读更多 →
深度解析macOS Sequoia Beta中OBS虚拟摄像头安装失败的技术解决方案

深度解析macOS Sequoia Beta中OBS虚拟摄像头安装失败的技术解决方案

深度解析macOS Sequoia Beta中OBS虚拟摄像头安装失败的技术解决方案 【免费下载链接】obs-studio OBS Studio - Free and open source software for live streaming and screen recording 项目地址: https://gitcode.com/GitHub_Trending/ob/obs-studio 在macOS Sequoia…

2026/8/10 19:34:08 阅读更多 →

日新闻

GraphQL-CSS API全解析:useGqlCSS、GqlCSS组件与getStyles实用指南

GraphQL-CSS API全解析:useGqlCSS、GqlCSS组件与getStyles实用指南

GraphQL-CSS API全解析:useGqlCSS、GqlCSS组件与getStyles实用指南 【免费下载链接】graphql-css A blazing fast CSS-in-GQL™ library. 项目地址: https://gitcode.com/gh_mirrors/gr/graphql-css GraphQL-CSS是一个基于GraphQL的CSS-in-GQL™库&#xff0…

2026/8/10 0:00:02 阅读更多 →
告别语言障碍:KISS Translator 双语翻译插件终极指南

告别语言障碍:KISS Translator 双语翻译插件终极指南

告别语言障碍:KISS Translator 双语翻译插件终极指南 【免费下载链接】kiss-translator A simple, open source bilingual translation extension & Greasemonkey script (一个简约、开源的 双语对照翻译扩展 & 油猴脚本) 项目地址: https://gitcode.com/…

2026/8/10 0:00:02 阅读更多 →
BepInEx配置管理器:游戏插件配置的终极可视化解决方案

BepInEx配置管理器:游戏插件配置的终极可视化解决方案

BepInEx配置管理器:游戏插件配置的终极可视化解决方案 【免费下载链接】BepInEx.ConfigurationManager Plugin configuration manager for BepInEx 项目地址: https://gitcode.com/gh_mirrors/be/BepInEx.ConfigurationManager 你是否曾经因为游戏插件的复杂…

2026/8/10 0:00:02 阅读更多 →

周新闻

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁 【免费下载链接】baidupankey 在线查询网盘提取码(维护中 rm repo) 项目地址: https://gitcode.com/gh_mirrors/ba/baidupankey 你是否曾经在深夜寻找一份重要资料&#x…

2026/8/10 1:05:29 阅读更多 →
如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南 【免费下载链接】chinese_license_plate_generator 中国车牌生成器 项目地址: https://gitcode.com/gh_mirrors/ch/chinese_license_plate_generator 中国车牌生成器是一个基于Python的开源项目&#xff0c…

2026/8/10 1:05:29 阅读更多 →
收藏!小白程序员轻松入门大模型,从Harness工程开始实践

收藏!小白程序员轻松入门大模型,从Harness工程开始实践

文章强调学习大模型不应只关注模型本身,而应重视模型外的系统搭建,即Harness。提出AgentModelHarness的实用公式,详细介绍Harness的四个层次:持久化层、执行层、控制层和观察与验证层。文章还探讨了上下文工程、工具设计、AGENTS.…

2026/8/10 1:05:29 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/10 17:07:33 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/10 1:05:29 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/10 17:07:33 阅读更多 →