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

📅 发布时间:2026/8/15 23:52:30
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 Jaeger3. 运行与验证3.1 启动3.2 触发业务3.3 Jaeger 看 Trace3.4 Prometheus 看指标1. 演示说明1.1 本篇要做什么上篇我们实现了「订单 → 支付」业务链路的三个观测点order.create、payment.create、checkout.create并让Prometheus直接抓取应用暴露的/actuator/prometheus指标。但那只打通了Metrics指标一条信号。业务观测产生的Traces链路信息比如一次checkout里order和payment的父子嵌套关系、订单号、支付流水号等上下文还留在应用内部。本篇在同一个demo上把两条信号都收敛到OTLPOpenTelemetry Protocol协议上Metrics应用通过OTLP导出器把指标直接推给Prometheus。Traces应用通过OTLP导出器把链路直接推给Jaeger存储与展示。这样你在Jaeger里能看到checkout.create展开成order.create → payment.create的完整调用树在Prometheus里能看到相同业务产生的指标二者还能通过exemplar互相跳转。1.2 为什么可以直接推送数据过去想用OTLP把指标发给Prometheus中间必须架一个OpenTelemetry Collector——因为Prometheus是拉取式设计自己不会主动收OTLP。但现在不一样了两端都原生支持OTLPPrometheus从2.47起内置了OTLP 接收器OTLP receiver可以在/api/v1/otlp/v1/metrics直接接收POST上来的OTLP指标。Jaeger从1.35起原生内置OTLP接收器gRPC:4317、HTTP:4318应用可以把链路直接推给它。于是拓扑可以简化为应用只做一件事把指标和链路都按 OTLP 协议 POST 出去一个出口两种目的地。依赖一引、配置一写每次observe()的观测就同时产生Metrics低基数标签 →Timer指标 →OTLP推给Prometheus。Traces高基数属性 →OpenTelemetry Span→OTLP推给 Jaegercheckout.create会展开成order.create → payment.create的父子调用树。1.3 和上篇的主要区别对比项上篇Prometheus 直抓本篇OTLP 直连两端指标Prometheus 主动拉/actuator/prometheus应用 OTLP 主动推/api/v1/otlp/v1/metrics链路无应用 OTLP 主动推 Jaeger推/拉拉pull推push中间件无无两端原生收 OTLP2. 环境搭建2.1 引入依赖版本由spring-boot-starter-parent的BOM统一管理dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-actuator/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-webmvc/artifactId/dependency!-- 指标OTLP 协议推送 --dependencygroupIdio.micrometer/groupIdartifactIdmicrometer-registry-otlp/artifactId/dependency!-- 链路OpenTelemetry bridge OTLP 导出Boot 4 独立模块 --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-micrometer-tracing-opentelemetry/artifactId/dependency!-- OTel 桥接把 Micrometer 转成 OpenTelemetry --dependencygroupIdio.micrometer/groupIdartifactIdmicrometer-tracing-bridge-otel/artifactId/dependency!-- OTel OTLP ExporterTracing 通过 OTLP 导出 --dependencygroupIdio.opentelemetry/groupIdartifactIdopentelemetry-exporter-otlp/artifactId/dependencyspring-boot-micrometer-tracing-opentelemetry是Boot 4新增的独立模块负责将Micrometer Observation变成OpenTelemetry Span并通过OTLP导出。OTLP Metrics相关三组依赖依赖干什么spring-boot-micrometer-tracing-opentelemetrySpring Boot 自动装配接线模块绑定配置类、创建 OTel 链路导出相关 Beanmicrometer-tracing-bridge-otel桥接层将 Micrometer Observation 转换为 OpenTelemetry Spanopentelemetry-exporter-otlpOTLP 导出实现负责把 Span 通过 HTTP/gRPC 发送至 OTel CollectorMetrics指标两组依赖依赖模式说明micrometer-registry-prometheus拉pull自包含Boot 4 自动装配出 PrometheusMeterRegistry 并暴露 /actuator/prometheusPrometheus 来抓。只要引入 actuator 即可无需额外导出组件micrometer-registry-otlp推push自包含发送器Jar内置OtlpHttpMetricsSender不需要像链路追踪额外引入 exporter jarMicrometer 原生实现OTLP指标HTTP客户端周期推送指标至OTel Collector这里只走 OTLP 推送就删掉micrometer-registry-prometheus2.2 应用配置两个最容易写错的地方url/endpoint必须是完整路径Micrometer的OTLPurl是整体当完整地址用的不会自动拼/v1/metrics所以指标那行要精确到/api/v1/otlp/v1/metrics链路要精确到/v1/traces。链路属性名是 Boot 4 新命名management.otlp.tracing.endpoint在4.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完整参考YAMLmanagement: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:1402.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完整参考YAMLmanagement: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-ssl2.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.time15d---web.enable-lifecycle---web.enable-otlp-receiver---enable-featureotlp-write-receiverports:-9090:9090volumes:-./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.id3. 运行与验证3.1 启动# 1) 起 Prometheus Jaegerdockercompose up-d# 2) 起应用cdmicrometer-boot-demo mvn spring-boot:run启动后应用会异步向两个OTLP端点推送Prometheus/Jaeger没起时应用也能正常启动只是日志出现连接报错。3.2 触发业务# 下单curl-XPOSThttp://localhost:8080/api/order/create?orderNoNO-001userId1001orderTypeNORMAL# 支付成功curl-XPOSThttp://localhost:8080/api/order/pay?orderIdORD-TEST001payChannelWECHAT# 支付失败演示错误链路curl-XPOSThttp://localhost:8080/api/order/pay?orderIdORD-TEST002payChannelFAIL# 结算下单 支付 嵌套curl-XPOSThttp://localhost:8080/api/checkout?orderNoNO-002userId1002orderTypeVIP3.3 Jaeger 看 Trace打开http://localhost:16686Service选spring-micrometer-serviceSearch即可看到请求的链路。最值得看的是checkout那条三个观测自动形成父子调用树3.4 Prometheus 看指标打开http://localhost:9090查看某个指标order_create_seconds_count{instance192.168.7.84:8080,jobspring-micrometer-service}几点说明OTLP翻译后的具体指标名与Prometheus版本的UTF-8命名、翻译策略有关以UI里实际看到的为准。OTLP接收器属于推模式与拉模式的差异要注意没有up指标因为不是scrape也没有抓取超时/拉取侧告警这些推模式语义需要另做监控。官方将其定位为实验性能力适合中小规模高吞吐场景仍建议用Collector缓冲或保留scrape。