news 2026/8/15 23:51:53

Micrometer 系列【63】统一观测:基于 Spring Boot 的生产级演示案例 | 基于 OTLP 集成 Prometheus + Jaeger

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Micrometer 系列【63】统一观测:基于 Spring Boot 的生产级演示案例 | 基于 OTLP 集成 Prometheus + Jaeger

文章目录

  • 1. 演示说明
    • 1.1 本篇要做什么
    • 1.2 为什么可以直接推送数据
    • 1.3 和上篇的主要区别
  • 2. 环境搭建
    • 2.1 引入依赖
    • 2.2 应用配置
      • 2.2.1 指标 OLTP 导出配置
      • 2.2.2 链路 OLTP 导出配置
    • 2.3 Docker Compose 部署 Prometheus + Jaeger
  • 3. 运行与验证
    • 3.1 启动
    • 3.2 触发业务
    • 3.3 Jaeger 看 Trace
    • 3.4 Prometheus 看指标

1. 演示说明

1.1 本篇要做什么

上篇我们实现了「订单 → 支付」业务链路的三个观测点(order.createpayment.createcheckout.create),并让Prometheus直接抓取应用暴露的/actuator/prometheus指标。

但那只打通了Metrics(指标)一条信号。业务观测产生的Traces(链路)信息,比如一次checkoutorderpayment的父子嵌套关系、订单号、支付流水号等上下文还留在应用内部。

本篇在同一个demo上,把两条信号都收敛到OTLP(OpenTelemetry Protocol)协议上:

  • Metrics:应用通过OTLP导出器把指标直接推给Prometheus
  • Traces:应用通过OTLP导出器把链路直接推给Jaeger存储与展示。

这样,你在Jaeger里能看到checkout.create展开成order.create → payment.create的完整调用树;在Prometheus里能看到相同业务产生的指标;二者还能通过exemplar互相跳转。


1.2 为什么可以直接推送数据

过去想用OTLP把指标发给Prometheus,中间必须架一个OpenTelemetry Collector——因为Prometheus是"拉取式"设计,自己不会主动收OTLP

但现在不一样了,两端都原生支持OTLP

  • Prometheus:从2.47起内置了OTLP 接收器(OTLP receiver),可以在/api/v1/otlp/v1/metrics直接接收POST上来的OTLP指标。
  • Jaeger:从1.35起原生内置OTLP接收器(gRPC:4317HTTP:4318),应用可以把链路直接推给它。

于是拓扑可以简化为:

应用只做一件事:把指标和链路都按 OTLP 协议 POST 出去,一个出口两种目的地。

依赖一引、配置一写,每次observe()的观测就同时产生:

  1. Metrics:低基数标签 →Timer指标 →OTLP推给Prometheus
  2. Traces:高基数属性 →OpenTelemetry SpanOTLP推给 Jaeger,checkout.create会展开成order.create → payment.create的父子调用树。

1.3 和上篇的主要区别

对比项上篇:Prometheus 直抓本篇:OTLP 直连两端
指标Prometheus 主动拉/actuator/prometheus应用 OTLP 主动推/api/v1/otlp/v1/metrics
链路应用 OTLP 主动推 Jaeger
推/拉拉(pull)推(push)
中间件无(两端原生收 OTLP)

2. 环境搭建

2.1 引入依赖

版本由spring-boot-starter-parentBOM统一管理:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webmvc</artifactId></dependency><!-- 指标:OTLP 协议推送 --><dependency><groupId>io.micrometer</groupId><artifactId>micrometer-registry-otlp</artifactId></dependency><!-- 链路:OpenTelemetry bridge + OTLP 导出(Boot 4 独立模块) --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-micrometer-tracing-opentelemetry</artifactId></dependency><!-- OTel 桥接:把 Micrometer 转成 OpenTelemetry --><dependency><groupId>io.micrometer</groupId><artifactId>micrometer-tracing-bridge-otel</artifactId></dependency><!-- OTel OTLP Exporter:Tracing 通过 OTLP 导出 --><dependency><groupId>io.opentelemetry</groupId><artifactId>opentelemetry-exporter-otlp</artifactId></dependency>

spring-boot-micrometer-tracing-opentelemetryBoot 4新增的独立模块,负责将Micrometer Observation变成OpenTelemetry Span,并通过OTLP导出。

OTLP Metrics相关三组依赖:

依赖干什么
spring-boot-micrometer-tracing-opentelemetrySpring Boot 自动装配接线模块,绑定配置类、创建 OTel 链路导出相关 Bean
micrometer-tracing-bridge-otel桥接层:将 Micrometer Observation 转换为 OpenTelemetry Span
opentelemetry-exporter-otlpOTLP 导出实现,负责把 Span 通过 HTTP/gRPC 发送至 OTel Collector

Metrics指标两组依赖:

依赖模式说明
micrometer-registry-prometheus拉(pull)自包含:Boot 4 自动装配出 PrometheusMeterRegistry 并暴露 /actuator/prometheus,Prometheus 来抓。只要引入 actuator 即可,无需额外导出组件
micrometer-registry-otlp推(push)自包含发送器:Jar内置OtlpHttpMetricsSender,不需要像链路追踪额外引入 exporter jar;Micrometer 原生实现OTLP指标HTTP客户端,周期推送指标至OTel Collector

这里只走 OTLP 推送,就删掉micrometer-registry-prometheus

2.2 应用配置

两个最容易写错的地方:

  • url/endpoint必须是完整路径MicrometerOTLPurl是整体当完整地址用的(不会自动拼/v1/metrics),所以指标那行要精确到/api/v1/otlp/v1/metrics;链路要精确到/v1/traces
  • 链路属性名是 Boot 4 新命名management.otlp.tracing.endpoint4.0已标记废弃(error级别,写了会启动报错),改用management.opentelemetry.tracing.export.otlp.endpoint

另外:在Micrometer 1.17/Boot 4.1(你这个模块的版本)里,指标OTLP导出只支持HTTP/Protobuf,不支持gRPC导出。

2.2.1 指标 OLTP 导出配置

src/main/resources/application.yaml追加:

management:# —— 指标:OTLP 直接推给 Prometheus 的原生 OTLP 接收器 ——otlp:metrics:export:url:http://localhost:9090/api/v1/otlp/v1/metricsstep:10s# 推送周期,演示调小;生产默认 1m

完整参考YAML

management:otlp:metrics:export:# ===================== PushRegistryProperties 父类通用推送配置 =====================# 是否开启 OTLP Metrics 指标导出enabled:true# 指标聚合上报周期(步进窗口),聚合完成后批量推送到OTLP Collectorstep:30s# OTLP 请求建立连接超时时间,跨机房/公网环境建议适度调大connect-timeout:2s# OTLP 请求读取响应超时,Collector负载较高时容易触发超时read-timeout:15s# 单次网络请求最多打包发送的指标条数,指标量大避免单包过大;太小会产生大量请求batch-size:5000# ===================== OtlpMetricsProperties OTLP 专有配置 =====================# OTLP 服务地址# HTTP协议:http://host:4318/v1/metricsurl:http://otel-collector:4318/v1/metrics# 传输压缩模式:NONE / GZIP,高指标量场景推荐开启gzip降低网络流量compression-mode:gzip# 聚合时序类型:CUMULATIVE(累积值,默认) / DELTA(增量值)# CUMULATIVE:上报持续累加数值,后端计算差值;兼容性最好,绝大多数存储支持# DELTA:上报周期内增量;注意很多OTLP后端不支持,随意修改会丢指标aggregation-temporality:cumulative# 指标导出时间单位,Micrometer内部计时为纳秒,导出时统一转换base-time-unit:milliseconds# 默认直方图类型:# EXPLICIT_BUCKET_HISTOGRAM 显式桶直方图(配合手动配置bucket边界,和Prometheus原生一致)# EXPONENTIAL_BUCKET_HISTOGRAM 指数直方图(自动生成桶,无需预设边界)histogram-flavor:explicit_bucket_histogram# 指数直方图精度参数,取值范围0~20,数值越大精度越高、生成桶数量越多max-scale:20# 指数直方图最大桶数量,仅对 EXPONENTIAL_BUCKET_HISTOGRAM 生效max-bucket-count:160# 是否额外为直方图发布max最大值Gauge指标,部分监控面板依赖该指标展示最大值publish-max-gauge-for-histograms:true# 自定义HTTP请求头,常用于鉴权、传递租户标识headers:X-Tenant:business-a# SSL配置,关联Spring Boot SSL Bundle统一证书管理ssl:bundle:otlp-ssl# ===================== Meter 维度:单指标粒度覆盖全局直方图配置 =====================# 优先级:单指标配置 > 全局配置 > Micrometer内置默认值meter:http.server.requests:histogram-flavor:exponential_bucket_histogrammax-bucket-count:140

2.2.2 链路 OLTP 导出配置

management:# —— 链路:OTLP 直接推给 Jaeger 的 OTLP HTTP 接收器 ——# Boot 4 起属性名从 management.otlp.tracing.* 迁移为 management.opentelemetry.tracing.export.otlp.*opentelemetry:tracing:export:otlp:endpoint:http://localhost:4318/v1/tracestransport:http# —— 采样 ——tracing:sampling:probability:1.0# 演示全采样;生产默认 0.1

完整参考YAML

management:opentelemetry:tracing:export:otlp:# OTLP Collector 接入地址# HTTP transport: http://otel-collector:4318/v1/traces# GRPC transport: http://otel-collector:4317endpoint:http://otel-collector:4318/v1/traces# 完整调用总超时:DNS解析、TCP连接、发送span、服务端处理、接收响应全过程上限# 包含所有重试、重定向耗时,超时后本次批次span丢弃timeout:10s# TCP连接建立超时时间connect-timeout:10s# 传输协议:HTTP / GRPC# GRPC吞吐量更高,大规模链路推荐;HTTP便于抓包调试transport:HTTP# 传输负载压缩:GZIP / NONE# 链路量较大时开启GZIP降低网络流量消耗compression:GZIP# 自定义请求头,常用于鉴权、租户隔离headers:X-Tenant:business-aAuthorization:Bearer ${OTEL_TOKEN:}# SSL配置,关联Spring Boot SSL Bundle,访问HTTPS类型OTLP端点时使用ssl:bundle:otlp-ssl

2.3 Docker Compose 部署 Prometheus + Jaeger

就两个服务:

services:prometheus:image:prom/prometheus:latestcontainer_name:ob-prometheuscommand:-'--config.file=/etc/prometheus/prometheus.yml'-'--storage.tsdb.path=/prometheus'-'--storage.tsdb.retention.time=15d'-'--web.enable-lifecycle'-'--web.enable-otlp-receiver'-'--enable-feature=otlp-write-receiver'ports:-"9090:9090"volumes:-./prometheus.yml:/etc/prometheus/prometheus.ymljaeger:image:jaegertracing/all-in-one:latestcontainer_name:ob-jaegerports:-"16686:16686"# Jaeger UI-"4318:4318"# OTLP HTTP(应用推 traces 走这个)-"4317:4317"# OTLP gRPC(预留)

指标是进来的,Prometheus不需要写任何scrape任务

prometheus.yml可以增加服务全局属性:

otlp:promote_resource_attributes:-service.name-service.instance.id

3. 运行与验证

3.1 启动

# 1) 起 Prometheus + Jaegerdockercompose up-d# 2) 起应用cdmicrometer-boot-demo mvn spring-boot:run

启动后应用会异步向两个OTLP端点推送;Prometheus/Jaeger没起时应用也能正常启动,只是日志出现连接报错。

3.2 触发业务

# 下单curl-XPOST"http://localhost:8080/api/order/create?orderNo=NO-001&userId=1001&orderType=NORMAL"# 支付成功curl-XPOST"http://localhost:8080/api/order/pay?orderId=ORD-TEST001&payChannel=WECHAT"# 支付失败(演示错误链路)curl-XPOST"http://localhost:8080/api/order/pay?orderId=ORD-TEST002&payChannel=FAIL"# 结算:下单 + 支付 嵌套curl-XPOST"http://localhost:8080/api/checkout?orderNo=NO-002&userId=1002&orderType=VIP"

3.3 Jaeger 看 Trace

打开http://localhost:16686Servicespring-micrometer-serviceSearch即可看到请求的链路。

最值得看的是checkout那条,三个观测自动形成父子调用树:

3.4 Prometheus 看指标

打开http://localhost:9090查看某个指标:

order_create_seconds_count{instance="192.168.7.84:8080",job="spring-micrometer-service"}

几点说明:

  • OTLP翻译后的具体指标名与Prometheus版本的UTF-8命名、翻译策略有关,以UI里实际看到的为准。
  • OTLP接收器属于推模式,与拉模式的差异要注意:没有up指标(因为不是scrape),也没有抓取超时/拉取侧告警,这些推模式语义需要另做监控。
  • 官方将其定位为实验性能力,适合中小规模;高吞吐场景仍建议用Collector缓冲或保留scrape

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/15 23:49:45

Hermes Agent 与 AutoGPT 有什么区别?

核心结论&#xff08;一句话&#xff09; AutoGPT 是无状态的「一次性任务执行器」——单次运行、做完即忘&#xff1b;Hermes Agent 是有状态的「持久化学习系统」——跨会话记忆 自动沉淀技能 越用越强。 两者本质差异在于 时间维度&#xff1a;AutoGPT 解决"当前任务…

作者头像 李华
网站建设 2026/8/15 23:48:15

Linux 中文本处理:cut 和 awk命令

cut 和 awk 都是 Linux 中用于文本处理的命令行工具&#xff0c;常用于从文件或数据流中提取、处理和分析文本。cut 偏向简单、快速的列提取&#xff0c;而 awk 是一个完整的文本处理编程语言&#xff0c;功能强大得多。一、cut 命令&#xff1a;简单列提取cut 用于按列&#x…

作者头像 李华
网站建设 2026/8/15 23:40:08

GLM ZCode AI编程助手实战:从安装配置到项目开发全指南

最近&#xff0c;很多开发者朋友在群里讨论一个事儿&#xff1a;智谱AI的GLM大模型和ZCode编程助手&#xff0c;突然宣布对百万用户“重置用量”&#xff0c;并且伴随着新一轮的“价格战”。消息一出&#xff0c;有人欢呼“羊毛来了”&#xff0c;也有人疑惑“这是不是套路&…

作者头像 李华
网站建设 2026/8/15 23:35:37

第二十五章 个体理解工程

第二十五章 个体 第二十五章 个体理解工程 &#x1f4c5; 2026年08月14日&#x1f464; 东塬一老翁&#x1f4c2; 第一卷 个体人工智能理论基础 第二十五章 个体理解工程 ——Individual Understanding Model 25.1 个体理解的本质 在个体人工智能中&#xff0c;理解不是对…

作者头像 李华
网站建设 2026/8/15 23:29:33

Chrome Network面板全解析:从HTTP请求到性能优化的前端调试实战

1. 从“黑盒”到“透视”&#xff1a;为什么我们必须懂Network面板做前端开发或者网站性能优化&#xff0c;最怕的就是线上出问题。用户反馈“页面打不开”、“加载太慢了”&#xff0c;你这边代码看着一切正常&#xff0c;服务器日志也风平浪静。这时候&#xff0c;如果你还只…

作者头像 李华