OpenTelemetry 实践指南:汗青、架构与基本概念

[复制链接]
发表于 2024-10-5 06:52:30 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×


  配景    之前连续写过一些和 OpenTelemetry 相关的文章:
  

  • 实战:如何优雅的从 Skywalking 切换到 OpenTelemetry
  • 实战:如何编写一个 OpenTelemetry Extensions
  • 从一个 JDK21+OpenTelemetry 不兼容的题目讲起
  这些内容的前提是最好有一些 OpenTelemetry 的配景知识,看起来就不会那么枯燥,为此这篇文章就来做一个入门科普,方便一些对 OpenTelemetry 不是那么熟的朋侪快速掌握一些 OpenTelemetry 的基本概念。
  
  汗青发展

  早在 OpenTelemetry 诞生之前可观测可观测性这个概念就不停存在了,我记得我最早接触到这个概念是在 16 年当时的公司所利用的一个产品:pinpoint
        现如今这个项目依然比较活跃。
   
依然还记得当时通过它可以直接看到项目调用的拓扑图,在时间坐标上框出高延迟的点就能列出这些哀求,同时还能查看此时的运行日志日志。
  这样强大的功能对于一个刚工作一年的小白来说打击力实属太大了一点。
  后来才了解到 pinpoint 属于 APM 这类产品,类似的产品另有:
  

  • Apache SkyWalking
  • 美团的 CAT 等
  他们都是可以用于性能分析和链路追踪的产品,到后来公司的运维层面也接入过 Zabbix、open-falcon 之类的产品:

  17之后全面切换到 spring boot 时,也用过社区提供的 spring-boot-admin 项目:
  
这就是一个简单的可以监控监控 spring boot 应用的产品,用于展示 JVM 指标,或者本身也可以界说一些康健指标。
  
  再之后进入云原生体系后可观测可观测性的技术栈稍有变革。
  
  日志日志利用 Sidecar 代理的方式通过 Agent 将数据写入 ElasticSearch 中。 具体日志日志收罗方式可以参考之前的文章:
  

  • 在 kubernetes 环境下如何收罗日志
  而链路追踪则是利用的 skywalking,在 trace 这个范畴 skywalking 还是非常受大家喜爱的。
  不外最近也从 skywalking 切换到了我们本文所讲到的 OpenTelemetry,具体可以看之前的文章:
  

  • 实战:如何优雅的从 Skywalking 切换到 OpenTelemetry
  指标收罗利用的是天然也是 Prometheus 的那一套技术栈,只是 Prometheus 换为了与它完全兼容的 VictoriaMetric 目前是为了更省资源。
  客户端利用则是直接利用 Prometheus 的库举行指标暴露:
  1. <dependency>
  2.     <groupId>io.prometheus</groupId>
  3.     <artifactId>prometheus-metrics-core</artifactId>
  4.     <version>1.0.0</version>
  5. </dependency>
  6. <dependency>
  7.     <groupId>io.prometheus</groupId>
  8.     <artifactId>prometheus-metrics-instrumentation-jvm</artifactId>
  9.     <version>1.0.0</version>
  10. </dependency>
  11. <dependency>
  12.     <groupId>io.prometheus</groupId>
  13.     <artifactId>prometheus-metrics-exporter-httpserver</artifactId>
  14.     <version>1.0.0</version>
  15. </dependency>
复制代码
最终通过设置抓取策略,由 VictoriaMetrics 的 scrape 步伐来抓取指标最终写入到它本身的存储中:
  1. apiVersion: operator.victoriametrics.com/v1beta1  
  2. kind: VMPodScrape  
  3. metadata:  
  4.   name: kubernetes-pod-scrape  
  5.   namespace: monitoring  
  6. spec:  
  7.   podMetricsEndpoints:  
  8.     - scheme: http  
  9.       scrape_interval: "30s"  
  10.       path: /metrics  
  11.       relabelConfigs:  
  12.         - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]  
  13.           separator: ;  
  14.           regex: "true"  
  15.           replacement: $1  
  16.           action: keep  
  17.         # 端口相同  
  18.         - action: keep_if_equal  
  19.           source_labels: [ __meta_kubernetes_pod_annotation_prometheus_io_port, __meta_kubernetes_pod_container_port_number ]  
  20.         # 过滤INIT容器  
  21.         - action: drop  
  22.           source_labels: [ __meta_kubernetes_pod_container_init ]  
  23.           regex: "true"  
  24.         - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]  
  25.           separator: ;  
  26.           regex: (.+)  
  27.           target_label: __metrics_path__  
  28.           replacement: $1  
  29.           action: replace  
  30.         - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]  
  31.           separator: ;  
  32.           regex: ([^:]+)(?::\d+)?;(\d+)  
  33.           target_label: __address__  
  34.           replacement: $1:$2  
  35.           action: replace  
  36.         - separator: ;  
  37.           regex: __meta_kubernetes_pod_label_(.+)  
  38.           replacement: $1  
  39.           action: labelmap  
  40.         - source_labels: [__meta_kubernetes_namespace]  
  41.           separator: ;  
  42.           regex: (.*)  
  43.           target_label: kubernetes_namespace  
  44.           replacement: $1  
  45.           action: replace  
  46.         - source_labels: [__meta_kubernetes_pod_name]  
  47.           separator: ;  
  48.           regex: (.*)  
  49.           target_label: kubernetes_pod_name  
  50.           replacement: $1  
  51.           action: replace  
  52.       vm_scrape_params:  
  53.         stream_parse: true  
  54.   namespaceSelector:  
  55.     any: true
复制代码
       以上是 VM 提供的 CRD
    OpenTelemetry 诞生

  到此铺垫完成,不知道有没有发如今可观测可观测性中关键的三个部分:日志、指标、trace 都是利用不同的开源产品,从而会导致技术栈较多,维护起来天然也是比较麻烦的。
  这么一个软件范畴的核心本领天然必要提供一个完备方案的,将以上的不同技术栈都整合在一起,更加的方便开发者利用。
  在这之前也有两个社区想要做类似的事变:
  

  • OpenTracing
  • OpenCensus
  不外他们并没有统一整个可观测范畴,直到 2019 年 CNCF 社区公布建立 OpenTelemetry,并且将上述两个社区举行合并共同开发 OpenTelemetry。
        背靠 CNCF 云原生社区加上很多着名厂商的支持(Google、Amazon、Redhat 等),如今已经正式成为 CNCF 的顶级项目了。
    OpenTelemetry 架构介绍

  
  但我们打开 OpenTelemetry 社区的 GitHub 首页时,会看到有很多项目;第一反应应该是比较蒙的,下面我会偏重介绍一些比较重要的项目。
  在开始之前还是先简单介绍下 OpenTelemetry 的一些基础组件和概念:

  整个 OpenTelemetry 系统其实可以简单分为三个部分:
  

  • 客户端
  • OTel collector
  • 数据存储
  第一个客户端很好理解,也就是我们的业务应用;假如是 Java 应用只必要挂载一个 agent 就可以自动收罗系统的指标、链路信息、日志等上传到 Collector 中。
  也就是上图的左边部分。
  之后就是非常关键的组件 collector,它可以通过 OTLP 协议接收刚才提到的客户端上传的数据,然后再内部举行处理,最终输出到后续的存储系统中。
  Collector

  
        上图是 collector 的架构图
    由于 OpenTelemetry 设计之初就是要做到厂商无关,所以它就得做出更高层级的设计。
  关键点就是这里的 Receiver 和 Exporter 都是模块化的设计,第三方开发者可以基于它的尺度开发不同组件从而兼容不同的产品。
  Receiver:用于接收客户端上报的数据,不止是本身 agent 上报的数据,也可能会来自不同的厂商,比如 kubernetes、Kafka 等。
  Exporter:同理,可以将 receiver 收到的数据举行处理之后输出到不同的组件中;比如 Kafka/Pulsar/Promethus/Jaeger 等。
  比如我们可以利用 Nginx Receiver接收来着 Nginx 上报的数据。
  利用 MySQL Receiver接收来自 MySQL 的数据。
  固然通常我们利用最多的还是 OTLP Receiver,这是官方的 OTLP 协议的接收器,可以接受官方的一些指标,比如我们只利用了 Java Agent 举行数据上报时。
https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/receiver
  在这里是可以看到目前支持的所有第三方的 Receiver。
  
  
  OpenTelemetry 所支持的 Exporter 也很多,比如一些常见的存储:
  

  • clickhouse exporter
  • elasticsearch exporter
  • pulsar exporter
  • prometheus exporter
  • otlp http exporter
  Exporter 的利用场景很多:假如是指标相关的数据可以直接写入 Prometheus,假如是日志数据也可以直接写入 ElasticSearch。
  假如另有其他的特别需求(删减属性等)则可以写入消息队列,自行处理完之后再发往 collector 举行后续的处理。
  可能你已经发现了,由于 collector 非常的灵活,所以我们可以像搭积木一样组装我们的 receiver 和 exporter,它会以我们设置的流水线的方式举行调用,这样我们就可以实现任意可定制的处理逻辑。
  而这些流水线的组装对于客户端来说都是透明的,也就是说 collector 的更改完全不会影响到业务;业务只必要按照 OTLP 的格式上报数据即可。
  在之前的从 Skywalking 切换到 OpenTelemetry 的文章中有人问为什么要切换到 OpenTelemetry?
  从这里也能看得出来,OpenTelemetry 的灵活度非常高,借助于 Exporter 可以任意的更换后端存储,或者增加/删减一些不必要的指标数据等。
  
  固然我们也可以统一的在这里举行搜刮,可以列出所有的第三方集成的组件: https://opentelemetry.io/ecosystem/registry/
  
  OpenTelemetry 项目介绍

  opentelemetry-java

  介绍完基本的概念后,我们可以看看  OTel 社区的一些主要开源项目。

  这里我们还是以刚才的谁人架构图从作往右讲起,也就是主要分为客户端和 collector 端。
  
目前官方支持的客户端语言已经非常齐全了,大部分的版本都已经是 Stable 稳固版,意味着可以进入生产环境。
  这里我们以 Java 客户端为例:
此中我们重点关注下 opentelemetry-java 和 opentelemetry-java-instrumentation 这两个项目。
  我们用的最多的会是 opentelemetry-java-instrumentation,它会给我们提供一个 java agent 的 JAR 包:
  1. java -javaagent:path/to/opentelemetry-javaagent.jar \
  2.      -jar myapp.jar
复制代码
我们只必要在 Java 应用中加上该  agent 就可以实现日志、指标、trace 的自动上报。
  而且它还实现了不同框架、库的指标收罗与 trace。
  在这里可以查到支持的库与框架列表:

  https://github.com/open-telemetry/opentelemetry-java-instrumentation/blob/main/docs/supported-libraries.md#libraries--frameworks
        总之几乎就是你能想到和不能想到的都支持了。
    而 opentelemetry-java 我们直接利用的几率会小一些,opentelemetry-java-instrumentation 本身也是基于它创建的,可以理解为是 Java 版本的核心基础库,一些社区支持的组件就可以移动到 instrumentation 这个库中。
  比如我在上篇文章:从一个 JDK21+OpenTelemetry 不兼容的题目讲起中涉及到的 HostResourceProvider 资源加载就是从 opentelemetry-java 中移动到了 opentelemetry-java-instrumentation。
  具体可以参考:https://github.com/open-telemetry/opentelemetry-java/issues/4701
  collector

  
  之后就是 collector 的组件了,它同样的也有两个库:OpenTelemetry Collector 和 OpenTelemetry Collector Contrib
  其实通过他们的名字也可以看得出来,他们的作用与刚才的 Java 库类似:
  

  • opentelemetry-collector:由官方社区维护,提供了一些核心本领;比如只包含了最基本的 otlp 的 receiver 和 exporter。
  • opentelemetry-collector-contrib:包含了官方的 collector,同时更多的维护了社区提供的各种 receiver 和 exporter;就如上文提到的,一些社区组件(pulsar、MySQL、Kafka)等都维护在这个堆栈。
  而我们生产利用时通常也是直接利用 opentelemetry-collector-contrib,毕竟它所支持的社区组件更多。
  总结

  因为 OpenTelemetry 想要解决的是整个可观测范畴的所有需求,所以堆栈非常多,社区也很开放,感爱好的朋侪可以直接到场贡献,这么多 repo 总有一个适合你的。
  后续会继续讲解如何安装以及设置我们的 OpenTelemetry。
  参考链接:
  

  • https://github.com/pinpoint-apm/pinpoint
  • https://github.com/codecentric/spring-boot-admin
  • https://github.com/open-telemetry/opentelemetry-java
  • https://github.com/open-telemetry/opentelemetry-java-instrumentation
  • https://github.com/open-telemetry/opentelemetry-java/issues/4701
  往期推荐
   
  OpenTelemetry agent 对 Spring Boot 应用的影响:一次 SPI 失效的观察
      
  自动化测试在 Kubernetes Operator 开发中的应用:以 OpenTelemetry
      
  深入剖析:如何利用Pulsar和Arthas高效排查消息队列延迟题目
      
  日志架构演进:从会合式到分布式的Kubernetes日志策略
      
  实战:如何编写一个 OpenTelemetry Extensions
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表