Micrometer 系列【54】统一观测:Context | 上下文容器
文章目录1. 概述1.1 基础定义1.2 核心特征1.3 工作原理1创建阶段2启动观测3执行业务逻辑4观测结束2. 源码分析2.1 ContextView只读视图接口2.2 Context可变实现类2.3 ClientRequestObservationContext 上层扩展3. 完整示例3.1 自定义上下文容器3.2 自定义观测处理器3.3 业务服务类3.4 程序入口1. 概述1.1 基础定义一次观测生命周期内统一存放本次事件所有元数据、业务对象、标签、异常、链路信息的数据载体。一次WebClient请求 /HTTP Server请求 / 方法调用就是一次Observation整个事件从开始到结束需要一个数据载体里面装着Request、Response、URL模板、异常、自定义标签、父链路信息、自定义业务对象这个存放数据的容器就是就是上下文容器。在Micrometer Observation体系中只读对外视图ContextView可变实现Context业务扩展ClientRequestObservationContext、ServerRequestObservationContext等继承扩展1.2 核心特征生命周期绑定Observation容器随Observation创建而生观测结束后不再使用单一事件私有每个Observation拥有独立Context不会和其他请求互相污染读写分离模型业务代码持有可变Context写入数据所有处理器Metrics、Tracing Handler只能拿到只读ContextView只允许读取承载两类数据① 通用业务对象MapObject,ObjectRequest、Response、DTO② 可观测标签Low/High Cardinality KeyValue用于指标、Trace Span属性1.3 工作原理1创建阶段开发者提前组装上下文填充本次事件所有信息Observation内部持有上下文引用// 创建业务扩展上下文容器ClientRequestObservationContextcontextnewClientRequestObservationContext(request);context.setUriTemplate(/order/{id});context.addLowCardinalityKeyValue(...);// 绑定到 ObservationObservationobservationObservation.createNotStarted(http.client.requests,()-context,registry);2启动观测触发所有注册的ObservationHandler#onStart(ContextView)处理器从Context中获取数据进行相关处理。比如链路追踪TracingHandler可以读取parentObservation获取父Span信息创建子Span读取contextView.getContextualName()/getName()设置Span名称读取高低基数KeyValues作为Span初始Attributes创建Trace Scope把TraceContext (traceId/spanId)设置到当前线程传给Handler的是ContextView只读视图禁止处理器修改容器数据。3执行业务逻辑业务代码可以继续操作原始可变Context设置异常context.setError(throwable)追加标签、存入返回对象response4观测结束observation.stop()触发依次执行Handler的onStop(ContextView)Micrometer Metrics Handler读取低基数标签生成Prometheus指标Timer/CounterTracing Handler如Brave/Otel读取全部标签构建Span写入链路追踪观测完成后上下文不再被框架使用异步场景需要开发者注意不要继续复用。2. 源码分析整体分层关系ContextView只读视图←Context可变实现← 业务扩展类ClientRequestObservationContext2.1 ContextView只读视图接口设计意图读写分离对外传给ObservationHandler、ObservationConvention的统一类型是ContextView只能读不能修改上下文。只有创建Observation的业务代码持有可变Context实例防止Handler随意篡改观测上下文。interfaceContextViewObservation基础标识字段方法作用getName()Observation 固定名称如http.client.requests指标名主体getContextualName()运行时动态名称例如 HTTP 方法路径用于 span namegetParentObservation()父 Observation构建链路追踪父子关系getError()本次观测发生的异常用于标记 span error、指标异常标签通用业务容器KV Map字段ConcurrentHashMapObject,Object map自定义业务数据仓库存放业务自定义对象getRequired不存在直接抛IllegalArgumentException适合强依赖场景。TTget(Objectkey);TTgetRequired(Objectkey);booleancontainsKey(Objectkey);TTgetOrDefault(...)Micrometer强制区分低基数 Low Cardinality / 高基数 High Cardinality方法清单KeyValuesgetLowCardinalityKeyValues();KeyValuesgetHighCardinalityKeyValues();KeyValuegetLowCardinalityKeyValue(Stringkey);KeyValuegetHighCardinalityKeyValue(Stringkey);KeyValuesgetAllKeyValues();规则ObservationConvention会生成一批标准标签通过addLowCardinalityKeyValue()添加的标签追加到Convention生成标签集合Handler在处理metrics/tracing时会分别读取两类标签做不同处理。2.2 Context可变实现类SuppressWarnings(unchecked)classContextimplementsContextView内部存储结构// 通用业务对象存储privatefinalMapObject,ObjectmapnewConcurrentHashMap();// 低基数标签privatefinalMapString,KeyValuelowCardinalityKeyValuesnewConcurrentHashMap();// 高基数标签privatefinalMapString,KeyValuehighCardinalityKeyValuesnewConcurrentHashMap();// 基础元数据privateStringname;privateStringcontextualName;privateThrowableerror;privateObservationViewparentObservation;全部使用ConcurrentHashMap→Observation可能跨线程使用线程安全设计。新增可变操作ContextView没有元数据settersetName / setContextualName / setParentObservation / setError业务map操作put / remove / computeIfAbsent / clear标签操作addLowCardinalityKeyValue / removeLowCardinalityKeyValue批量操作setParentFromCurrentObservation()自动从registry.getCurrentObservation()获取当前线程活跃Observation作为父节点自动构建链路上下文。2.3 ClientRequestObservationContext 上层扩展上次模块Maven: org.springframework:spring-web:6.2.16RequestReplySenderContext是Spring基于Micrometer Context封装的通用客户端请求-应答上下文模板内置request/response对象持有支持传播tracing载体Propagation carrier注入HTTP Headertraceparent等publicclassClientRequestObservationContextextendsRequestReplySenderContextClientHttpRequest,ClientHttpResponse3. 完整示例场景单进程内部调用创建订单(根Observation) → 发起支付(子Observation)核心演示自定义业务Observation.Context上下文容器观测自动父子关系构建onStart/onStop生命周期、ContextView只读约束Low/High Cardinality标签区分不依赖任何Spring仅micrometer原生API3.1 自定义上下文容器自定义订单业务上下文容器继承Observation.Context可变上下文。业务代码可写入字段、高低基数标签、自定义对象作为一次订单观测的数据包供后续Handler读取。publicclassOrderObservationContextextendsObservation.Context{privateStringorderNo;privateLonguserId;privateStringorderType;publicStringgetOrderNo(){returnorderNo;}publicvoidsetOrderNo(StringorderNo){this.orderNoorderNo;// 高基数唯一流水号仅用于Trace禁止指标Tag防止时序爆炸addHighCardinalityKeyValue(KeyValue.of(order.no,orderNo));}publicLonggetUserId(){returnuserId;}publicvoidsetUserId(LonguserId){this.userIduserId;addHighCardinalityKeyValue(KeyValue.of(user.id,String.valueOf(userId)));}publicStringgetOrderType(){returnorderType;}publicvoidsetOrderType(StringorderType){this.orderTypeorderType;// 低基数枚举维度Metrics指标 Trace链路都可以使用addLowCardinalityKeyValue(KeyValue.of(order.type,orderType));}}支付业务专属上下文容器独立上下文每一次支付观测创建独立实例隔离数据。publicclassPaymentObservationContextextendsObservation.Context{privateStringorderNo;privateStringpayChannel;publicStringgetOrderNo(){returnorderNo;}publicvoidsetOrderNo(StringorderNo){this.orderNoorderNo;addHighCardinalityKeyValue(KeyValue.of(pay.order.no,orderNo));}publicStringgetPayChannel(){returnpayChannel;}publicvoidsetPayChannel(StringpayChannel){this.payChannelpayChannel;addLowCardinalityKeyValue(KeyValue.of(pay.channel,payChannel));}}3.2 自定义观测处理器所有Handler入参为ContextView只读视图禁止修改上下文容器。监听观测生命周期onStart观测启动、onStop观测结束打印上下文信息演示数据消费逻辑。/** * 自定义日志处理器消费只读上下文 ContextView */publicclassBizLogObservationHandlerimplementsObservationHandlerObservation.ContextView{/** * 观测启动回调业务逻辑还未执行拿不到响应/异常 */OverridepublicvoidonStart(Observation.ContextViewcontextView){System.out.println(\n onStart );System.out.println(观测名称contextView.getName());System.out.println(父观测contextView.getParentObservation());if(contextViewinstanceofOrderObservationContextctx){System.out.println([订单上下文] orderNoctx.getOrderNo(), typectx.getOrderType());System.out.println(自定义扩展数据ctx.get(ext.info));}if(contextViewinstanceofPaymentObservationContextctx){System.out.println([支付上下文] orderNoctx.getOrderNo(), channelctx.getPayChannel());}System.out.println(低基数标签集合contextView.getLowCardinalityKeyValues());System.out.println(\n);}/** * 观测结束回调业务执行完成可以读取异常、耗时相关信息 */OverridepublicvoidonStop(Observation.ContextViewcontextView){System.out.println(\n onStop );System.out.println(观测名称contextView.getName());ThrowableerrorcontextView.getError();if(error!null){System.out.println(观测异常error.getMessage());}System.out.println(\n);}/** * 匹配器只处理我们自定义的业务上下文过滤系统内置上下文 */OverridepublicbooleansupportsContext(Observation.ContextViewcontext){returncontextinstanceofOrderObservationContext||contextinstanceofPaymentObservationContext;}}3.3 业务服务类支付业务服务创建子Observation启动时自动寻找当前线程活跃观测自动构建父子链路。/** * 支付服务生成子观测 payment.create */publicclassPaymentService{privatefinalObservationRegistryregistry;publicPaymentService(ObservationRegistryregistry){this.registryregistry;}publicvoidpay(StringorderNo){// 创建支付专属上下文容器PaymentObservationContextpayContextnewPaymentObservationContext();payContext.setOrderNo(orderNo);payContext.setPayChannel(WECHAT);// 创建未启动观测绑定上下文容器ObservationpayObservationObservation.createNotStarted(payment.create,()-payContext,registry);// observe() 封装模板start() → 执行业务 → stop()payObservation.observe(()-{System.out.println(执行业务发起支付 orderNoorderNo);sleep(120);});}privatevoidsleep(longms){try{Thread.sleep(ms);}catch(InterruptedExceptione){thrownewRuntimeException(e);}}}订单业务服务创建根Observation内部调用PaymentService形成调用链路。业务发生异常时把异常写入上下文容器供Handler捕获。/** * 订单服务生成根观测 order.create */publicclassOrderService{privatefinalObservationRegistryregistry;privatefinalPaymentServicepaymentService;publicOrderService(ObservationRegistryregistry,PaymentServicepaymentService){this.registryregistry;this.paymentServicepaymentService;}publicvoidcreateOrder(StringorderNo,LonguserId,StringorderType){// 初始化订单上下文容器填充业务数据OrderObservationContextorderContextnewOrderObservationContext();orderContext.setOrderNo(orderNo);orderContext.setUserId(userId);orderContext.setOrderType(orderType);// put方式存放自定义对象不会自动成为标签需要手动读取orderContext.put(ext.info,订单附加备注信息);ObservationorderObservationObservation.createNotStarted(order.create,()-orderContext,registry);orderObservation.observe(()-{try{System.out.println(执行业务创建订单 orderNoorderNo);sleep(100);// 内部调用支付子观测自动关联父观测paymentService.pay(orderNo);}catch(Exceptione){// 将异常存入上下文容器onStop阶段处理器读取orderContext.setError(e);throwe;}});}privatevoidsleep(longms){try{Thread.sleep(ms);}catch(InterruptedExceptione){thrownewRuntimeException(e);}}}3.4 程序入口创建ObservationRegistry观测注册中心注册自定义Handler组装并执行业务流程。publicclassObservationMain{publicstaticvoidmain(String[]args){// 1. 创建观测注册中心ObservationRegistryregistryObservationRegistry.create();// 2. 注册自定义观测处理器registry.observationConfig().observationHandler(newBizLogObservationHandler());// 3. 初始化业务 BeanPaymentServicepaymentServicenewPaymentService(registry);OrderServiceorderServicenewOrderService(registry,paymentService);// 4. 执行完整业务流程orderService.createOrder(OD20260813_001,10001L,NORMAL);}}

相关新闻

Chateau框架API完全参考:轻松掌握聊天功能开发接口

Chateau框架API完全参考:轻松掌握聊天功能开发接口

Chateau框架API完全参考:轻松掌握聊天功能开发接口 【免费下载链接】Chateau Chateau is a framework for adding (or improving) chat functionality in any Android app 项目地址: https://gitcode.com/gh_mirrors/cha/Chateau Chateau是一款专为Android应…

2026/8/13 19:58:36 阅读更多 →
物流行业跨境报关自动化怎么做?企业级AI Agent落地架构与主流方案解析

物流行业跨境报关自动化怎么做?企业级AI Agent落地架构与主流方案解析

在当前全球贸易环境日益复杂的背景下,跨境物流企业正面临着报关链路长、HS Code归类难、单证非结构化数据多以及合规风控压力大等核心痛点。传统的“经验排柜Excel对账”模式已无法满足现代跨境电商及B2B贸易的高效履约需求。随着大模型落地与企业智能自动化技术的演…

2026/8/13 19:58:35 阅读更多 →
Golongpoll与Gin框架集成:构建高性能实时Web应用

Golongpoll与Gin框架集成:构建高性能实时Web应用

Golongpoll与Gin框架集成:构建高性能实时Web应用 【免费下载链接】golongpoll golang long polling library. Makes web pub-sub easy via HTTP long-poll servers and clients :smiley: :coffee: :computer: 项目地址: https://gitcode.com/gh_mirrors/go/golong…

2026/8/13 19:57:35 阅读更多 →

最新新闻

海萤物联网教程:sbc:基于python的C语言格式结构体和二进制转换库

海萤物联网教程:sbc:基于python的C语言格式结构体和二进制转换库

文章目录海萤物联网教程:sbc:基于python的C语言格式结构体和二进制转换库介绍开源Python和C对应类型使用说明示例海萤物联网教程:sbc:基于python的C语言格式结构体和二进制转换库 本文博客链接:http://blog.csdn.net/jdh99,作者:…

2026/8/13 21:08:29 阅读更多 →
如何永久保存微信聊天记录?WeChatMsg终极备份与智能分析完全指南

如何永久保存微信聊天记录?WeChatMsg终极备份与智能分析完全指南

如何永久保存微信聊天记录?WeChatMsg终极备份与智能分析完全指南 【免费下载链接】WeChatMsg 提取微信聊天记录,将其导出成HTML、Word、CSV文档永久保存,对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trendin…

2026/8/13 21:08:29 阅读更多 →
海萤物联网ntp服务上线

海萤物联网ntp服务上线

文章目录海萤物联网ntp服务上线开源介绍服务读取时间服务1读取时间服务2.返回的是结构体自定义错误码示例读取时间读取时区为2的时间读取时区为-6的时间读取结构体格式时间源码main.goconfig.go海萤物联网ntp服务上线 本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请…

2026/8/13 21:08:29 阅读更多 →
海萤物联网教程:Go SDK

海萤物联网教程:Go SDK

文章目录海萤物联网教程:Go SDK简介特点开源安装背景知识API默认参数绑定管道注册服务调用目的节点服务请求和应答数据格式完整示例ntp服务器开源地址ntp服务介绍读取时间服务1读取时间服务2.返回的是结构体开放服务示例读取时间服务1读取时间服务2海萤物联网教程&a…

2026/8/13 21:08:29 阅读更多 →
ANSYS apdl命令流笔记12-------仔细剖分glue(粘结)命令

ANSYS apdl命令流笔记12-------仔细剖分glue(粘结)命令

仔细剖分glue(粘结)命令一、作用二、使用条件三、使用方法:vglue、aglue、lglue四、使用glue命令后ansys对体、面、线、关键点的划分规则五、小测试 一、作用 把模型的重合边界变成公共边界,模型的个数不变 在使用粘结之前的两个体&#xff0…

2026/8/13 21:08:29 阅读更多 →
【预测模型-ELAMN预测】基于蚁群算法优化ELMAN神经网络实现数据回归预测matlab代码

【预测模型-ELAMN预测】基于蚁群算法优化ELMAN神经网络实现数据回归预测matlab代码

1 简介风能,作为一种重要,有潜力,无污染,可再生、可持续的能源,已经成为全球发电最为迅速的能源之一,越来越受到世界各国的青睐。近年来,为缓解能源短缺问题,改善环境,实现经济乃至人类的可持续发展,世界各国纷纷大力发展风能资源。然而,在实际操作中,风能固有的波动性和间歇性…

2026/8/13 21:07:28 阅读更多 →

日新闻

Visual Studio新建项目解决方案为空:系统性排查与修复指南

Visual Studio新建项目解决方案为空:系统性排查与修复指南

1. 问题现象与本质剖析如果你是一位.NET开发者,或者正准备踏入这个领域,那么Visual Studio(后面简称VS)绝对是你绕不开的伙伴。但有时候,这个伙伴会跟你开一个不大不小的玩笑:你满怀期待地点击“创建新项目…

2026/8/13 0:00:09 阅读更多 →
长春建设厅网站:普通人买房办事必看的真实指南与避坑攻略

长春建设厅网站:普通人买房办事必看的真实指南与避坑攻略

说实话,每次提起“长春建设厅网站”这几个字,我心里都挺有感触的。不是因为它有多高大上,也不是因为那里藏着什么不可告人的秘密,恰恰相反,是因为它太“接地气”了,或者说,它是咱们普通人想要在这个城市好好生活、安稳买房时,必须得翻过的一座“数据山”。很多新朋友第…

2026/8/13 0:00:09 阅读更多 →
Windows家庭版远程桌面多用户破解完整指南:RDPWrap终极解决方案

Windows家庭版远程桌面多用户破解完整指南:RDPWrap终极解决方案

Windows家庭版远程桌面多用户破解完整指南:RDPWrap终极解决方案 【免费下载链接】rdpwrap.ini RDPWrap.ini for RDP Wrapper Library by StasM 项目地址: https://gitcode.com/GitHub_Trending/rd/rdpwrap.ini 你是否曾为Windows家庭版无法支持多用户远程桌面…

2026/8/13 0:00:09 阅读更多 →

周新闻

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

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

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

2026/8/13 2:38:34 阅读更多 →
如何快速生成中国车牌图片:Python开源工具完整指南

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

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

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

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

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

2026/8/13 10:41:51 阅读更多 →

月新闻

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

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

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

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

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

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

2026/8/13 10:41:49 阅读更多 →
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/13 10:41:49 阅读更多 →