OpenTelemetrySpringCloudSleuthKafkaJager实现分布式跟踪
前言
分布式跟踪可让您深入了解特定服务在分布式软件系统中作为整体的一部分是如何执行的。它跟踪和记录从起点到目的地的请求以及它们经过的系统。
在本文中,我们将使用 OpenTelemetry、Spring Cloud Sleuth、Kafka 和 Jaeger 在三个 Spring Boot 微服务 中实现分布式跟踪。
我们先来看看分布式追踪中的一些基本术语。
跨度:表示系统内的单个工作单元。跨度可以相互嵌套以模拟工作的分解。例如,一个跨度可能正在调用一个 REST 端点,然后另一个子跨度可能是该端点调用另一个,等等在不同的服务中。
Trace:所有共享相同根跨度的跨度集合,或者更简单地说,将所有跨度创建为原始请求的直接结果。跨度的层次结构(每个跨度在根跨度旁边都有自己的父跨度)可用于形成有向无环图,显示请求在通过各种组件时的路径。
OpenTelemetry
OpenTelemetry ,也简称为 OTel,是一个供应商中立的开源 Observability 框架,用于检测、生成、收集和导出遥测数据,例如 跟踪 、 指标 和 日志 。作为 云原生 计算基金会 (CNCF) 的孵化项目,OTel 旨在提供与供应商无关的统一库和 API 集——主要用于收集数据并将其传输到某处。OTel 正在成为生成和管理遥测数据的世界标准,并被广泛采用。
Spring Cloud Sleuth
Sleuth 是一个由 Spring Cloud 团队管理和维护的项目,旨在将分布式跟踪功能集成到 Spring Boot 应用程序中。它作为一个典型Spring Starter的 . 以下是一些开箱即用的 Sleuth 工具:
在 Spring MVC 控制器(REST 端点)收到的请求通过 Kafka 或 MQ 等消息传递技术的请求用RestTemplate,WebClient等发出的请求
Sleuth 添加了一个拦截器,以确保在请求中传递所有跟踪信息。每次调用时,都会创建一个新的 Span。它在收到响应后关闭。
Sleuth 能够跟踪您的请求和消息,以便您可以将该通信与相应的日志条目相关联。您还可以将跟踪信息导出到外部系统以可视化延迟。
Jaeger
Jaeger 最初由 Uber 的团队构建,然后于 2015 年开源。它于 2017 年被接受为云原生孵化项目,并于 2019 年毕业。作为 CNCF 的一部分,Jaeger 是云原生 架构 中公认的项目。它的源代码主要是用 Go 编写的。Jaeger 的架构包括:
Instrumentation LibrariesCollectors查询服务和网页界面数据库存储
与 Jaeger 类似,Zipkin 在其架构中也提供了相同的组件集。尽管 Zipkin 是一个较老的项目,但 Jaeger 具有更现代和可扩展的设计。对于此示例,我们选择 Jaeger 作为后端。
追踪系统设计
让我们设计三个 Spring Boot 微服务:
customer-service-bff:使用backend for frontend模式,此服务位于 UI 和后端之间。它由 UI Web 应用程序调用,而后者又通过 REST API 调用调用后端客户服务。customer-service: 一个简单的客户 CRUD 服务。除了在 CRUD 操作时将数据持久化到其数据库之外,它还在创建、更新或删除客户记录时将事件发布到 Kafka。order-service:监听 Kafka 主题,使用客户创建/更新/删除的事件。
这三个微服务旨在:
通过 REST API (customer-service-bff和customer-service)进行通信通过 Kafka(customer-service和order-service)通过事件驱动的 pub/sub 进行通信
这是为了观察 OpenTelemetry 如何结合 Spring Cloud Sleuth 处理代码的自动检测以及生成和传输跟踪数据。上面的虚线捕获了微服务导出的跟踪数据的路径,通过OTLP(OpenTelemetry Protocol)传输到OpenTelemetry Collector,收集器依次处理并将跟踪数据导出到后端Jaeger进行存储和查询。
使用 monorepo,我们的项目结构如下:
第 1 步:添加 POM 依赖项
这是使用 OTel 和 Spring Cloud Sleuth 实现分布式跟踪的关键。我们的目标是不必手动检测我们的代码,因此我们依靠这些依赖项来完成它们设计的工作——自动检测我们的代码,除了跟踪实现、将遥测数据导出到 OTel 收集器等。
org.springframework.cloud spring-cloud-dependencies ${spring-cloud.version} pom import org.springframework.cloud spring-cloud-sleuth-otel-dependencies ${spring-cloud-sleuth-otel.version} import pom org.springframework.cloud spring-cloud-starter-sleuth org.springframework.cloud spring-cloud-sleuth-brave org.springframework.cloud spring-cloud-sleuth-otel-autoconfigure io.opentelemetry opentelemetry-exporter-otlp-trace
spring-cloud-dependencies: Spring Cloud 依赖spring-cloud-sleuth-otel-dependencies: Spring Cloud Sleuth OpenTelemetry 依赖项spring-cloud-starter-sleuth:Sleuth 通过模块中可用的桥与 OpenZipkin Brave 跟踪器集成spring-cloud-sleuth-brave。由于我们将在示例中使用 OpenTelemetry 跟踪器,因此我们spring-cloud-sleuth-brave从spring-cloud-starter-sleuth依赖项中排除,而是添加spring-cloud-sleuth-otel-autoconfigure依赖项。这将基于Brave的默认跟踪实现替换为基于 OpenTelemetry 的实现。opentelemetry-exporter-otlp-trace:这是 Spring Cloud Sleuth OTel 中向 OpenTelemetry Collector 发送跟踪的组件。
第 2 步:OpenTelemetry 配置
OpenTelemetry 收集器端点
对于每个微服务,我们需要在其中添加以下配置application.yml(请参阅下面部分中的示例片段)。spring.sleuth.otel.exporter.otlp.endpoint主要是配置OTel Collector端点。它告诉导出器,在我们的例子中是 Sleuth,通过 OTLP 将跟踪数据发送到指定的收集器端点http://otel-collector:4317。注意otel-collector端点 URL 来自otel-collector图像的 docker-compose 服务。
跟踪数据概率抽样
spring.sleuth.otel.config.trace-id-ratio-based属性定义了跟踪数据的采样概率。它根据提供给采样器的分数对一部分迹线进行采样。概率抽样允许 OpenTelemetry 跟踪用户通过使用随机抽样技术降低跨度收集成本。如果该比率小于 1.0,则某些迹线将不会被导出。对于此示例,我们将采样配置为 1.0、100%。
有关其他 OTel Spring Cloud Sleuth 属性,请参阅常见应用程序属性。
spring: application: name: customer-service sleuth: otel: config: trace-id-ratio-based: 1.0 exporter: otlp: endpoint: http://otel-collector:4317
OpenTelemetry 配置文件
我们需要项目根目录下的 OTel 配置文件otel-config.yaml。内容如下。此配置文件定义了 OTel 接收器、处理器和导出器的行为。正如我们所看到的,我们定义了我们的接收器来监听 gRPC 和 HTTP,处理器使用批处理和导出器作为 jaeger 和日志记录。
extensions: memory_ballast: size_mib: 512 zpages: endpoint: 0.0.0.0:55679 receivers: otlp: protocols: grpc: http: processors: batch: exporters: logging: logLevel: debug jaeger: endpoint: jaeger-all-in-one:14250 tls: insecure: true service: pipelines: traces: receivers: [ otlp ] processors: [ batch ] exporters: [ logging, jaeger ] extensions: [ memory_ballast, zpages ]
第 3 步:docker-compose 将所有内容串在一起
让我们看看我们需要启动哪些 docker 容器来运行这三个微服务并观察它们的分布式跟踪,前三个微服务在上面的部分中进行了解释。
customer-service-bffcustomer-serviceorder-servicepostgres-customer: 数据库customer-servicepostgres-order: 数据库order-servicejaeger-all-in-one:运行所有 Jaeger 后端组件和 UI 的单个图像otel-collector:OpenTelemetry 追踪引擎,接收、处理、导出追踪数据到后端zookeeper:跟踪Kafka集群中节点的状态,维护Kafka主题和消息列表kafka:发布/订阅事件流处理平台
services: customer-service-bff: image: customer-service-bff:0.0.1-SNAPSHOT ports: - "8080:8080" depends_on: - zookeeper - kafka customer-service: image: customer-service:0.0.1-SNAPSHOT ports: - "8081:8081" depends_on: - zookeeper - kafka - postgres-customer environment: - SPRING_DATASOURCE_JDBC-URL=jdbc:postgresql://postgres-customer:5432/customerservice - SPRING_DATASOURCE_USERNAME=postgres - SPRING_DATASOURCE_PASSWORD=postgres - SPRING_JPA_HIBERNATE_DDL_AUTO=update order-service: image: order-service:0.0.1-SNAPSHOT ports: - "8082:8082" depends_on: - zookeeper - kafka - postgres-order environment: - SPRING_DATASOURCE_JDBC-URL=jdbc:postgresql://postgres-order:5432/orderservice - SPRING_DATASOURCE_USERNAME=postgres - SPRING_DATASOURCE_PASSWORD=postgres - SPRING_JPA_HIBERNATE_DDL_AUTO=update postgres-customer: image: postgres ports: - "5432:5432" environment: - POSTGRES_PASSWORD=postgres - POSTGRES_USER=postgres - POSTGRES_DB=customerservice postgres-order: image: postgres ports: - "5431:5431" environment: - POSTGRES_PASSWORD=postgres - POSTGRES_USER=postgres - POSTGRES_DB=orderservice jaeger-all-in-one: image: jaegertracing/all-in-one:latest ports: - "16686:16686" - "14268" - "14250" otel-collector: image: otel/opentelemetry-collector:0.47.0 command: [ "--config=/etc/otel-collector-config.yaml" ] volumes: - ./otel-config.yaml:/etc/otel-collector-config.yaml ports: - "1888:1888" # pprof extension - "13133:13133" # health_check extension - "4317" # OTLP gRPC receiver - "55670:55679" # zpages extension depends_on: - jaeger-all-in-one zookeeper: image: confluentinc/cp-zookeeper:latest environment: ZOOKEEPER_CLIENT_PORT: 2181 ZOOKEEPER_TICK_TIME: 2000 ports: - 22181:2181 kafka: image: confluentinc/cp-kafka:latest depends_on: - zookeeper ports: - 29092:29092 environment: KAFKA_BROKER_ID: 1 KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092,PLAINTEXT_HOST://localhost:29092 KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
运行docker-compose up -d以调出所有九个容器:
第 4 步:追踪数据在行动
快乐之路
现在,让我们启动customer-service-bff流程的入口点,以创建新客户。
启动 Jaeger UI, http://localhost:16686/ [url=https://link.zhihu.com/?target=http%3A//localhost%3A16686/%2C]按[/url]服务搜索customer-service-bff,单击Find Traces按钮,这是我们看到的创建客户跟踪:它跨越三个服务,总共跨越六个,持续时间 82.35 毫秒。
除了 Trace Timeline 视图(上面的屏幕截图),Jaeger 还提供了一个图形视图(Trace Graph在右上角的下拉菜单中选择):
三个微服务在 docker 中的日志输出显示相同的跟踪 id,以红色突出显示,并根据其应用程序名称显示不同的跨度 id(应用程序名称及其对应的跨度 id 以匹配的颜色突出显示)。在 的情况下customer-service,相同的 span id 从 REST API 请求传递到 Kafka 发布者请求。
错误场景
customer-service让我们在 docker 中暂停我们的PostgreSQL 数据库,然后重复从customer-service-bff. 500 internal server error正如预期的那样,我们得到了。检查 Jaeger,我们看到以下跟踪,异常堆栈跟踪抱怨SocketTimeoutException,再次如预期的那样。
识别长期运行的跨度
Jaeger UI 允许我们搜索超过指定最大持续时间的跟踪。例如,我们可以搜索所有耗时超过 1000 毫秒的跟踪。然后,我们可以深入研究长期运行的跟踪以调查其根本原因。
总结
在这个故事中,我们从 OpenTelemetry、Spring Cloud Sleuth 和 Jaeger 的角度解压了分布式跟踪,验证了 REST API 调用和 Kafka pub/sub 中分布式跟踪的自动检测。我希望这个故事能让你更好地理解这些跟踪框架和工具,尤其是 OpenTelemetry,以及它如何从根本上改变我们在 分布式系统 中进行可观察性的方式。
吃鸡空投节开启后,为什么没有幸运空投?究竟什么时候上线?前言务实不浮夸!我是你们的情报小能手,微笑十倍镜。本期和大家探讨一下,吃鸡手游和平精英空投节期间,幸运空投的相关问题!众所周知,和平精英在每年78月份都会上线自创的空投节,与毫无新
老输谁牛足秋,散装拼音来了!老师看了都摇头在学习拼音的过程中,家长们真是抓破了头皮,有些孩子,根本接受不了拼音,尤其到学习两拼和三拼的时候,更是闹出各种笑话在孩子们的世界里,没有读不出的拼音,没有不会读的汉字哈lg(蜜瓜)
三伏天来啦!宝宝们护理需要注意什么?一年中气温最高且潮湿闷热的日子三伏天,已在7月16日正式来袭。全国各地陆续进入烧烤模式,可怜的宝宝备受煎熬,非常容易中暑生病。然而,漫长的三伏天将持续一个多月,爸比妈咪们该如何应对
大自然探索神秘莫测百慕大百慕大三角,是一个非常神秘的地方。它位于美国东南岸对面的大西洋,即佛罗里达南端西印度群岛东端与百慕大群岛之间围成的三角形区域据记载,从19世纪起,常有途经该区域的船只或飞机无故失踪
石榴籽队实践日志Day6延续民族文化血脉,彰显文化自信力量石榴花开,同行西域2022年7月7日,北京化工大学经济管理学院石榴籽实践团队前往新疆巴里坤县哈萨克民俗博物馆和全国民族团结先进个人杨忠贤纪念堂,感受中华民族民俗文化的魅力和民族团结
广东城堡酒店终于等到开业,超值2日游含双早双晚,十分惬意江门鹤山玥湖豪华度假酒店五星级超值两日游,两人599含自助早餐海鲜自助晚餐超大泳池!点开我的头像,再点底部活动资讯,搜索关键词东古下单预定除了美丽如画的地方,如半岛城市,湛江以海鲜
黑龙江出海口,打造远东渔业走廊继续冰上丝绸之路系列。上文说了苏维埃港瓦尼诺港,本文沿着这两个港口北上270海里(约500公里),到达尼古拉耶夫斯克,也就是庙街。先看图庙街区位(底图来自中国自驾地理,侵删)站在庙
埃及行游影记(20)卢克索帝王谷(一)帝王谷也是卢克索的一个著名景区,开心帮我们办好手续之后,首先带我们进了一个展厅,和卡纳克神庙一样,游客大厅里也有一个关于帝王谷的沙盘模型。从这个模型就可以看出我们所在的帝王谷的地貌
上谷之咽喉,京师之右臂,在独石口众多遗迹中谜一样的独石庙遗址在赤城县北有一个名为独石口的关隘,它是明长城宣府镇上的一座重要关口,这是一处有着上谷之咽喉,京师之右臂之称的隘口,这里因西南二公里处有一座拔地而起的孤石,关口因此而得名。独石口处在
美丽中国网络媒体生态行樟子松故乡红花尔基的绿色崛起央视网消息(记者王静远彭俊于晓丹)走进红花尔基樟子松国家森林公园,首先映入眼帘的是一块写着樟子松故乡红花尔基的观赏石。红花尔基樟子松国家森林公园位于内蒙古自治区呼伦贝尔市鄂温克族自
html实现神墓逃亡小游戏(自适应)使用htmlcssjs实现以前神墓逃亡小游戏,不需要下载,只需要点击链接就可以体验,手机电脑都可以运行,源码链接在文章末尾,需要的请自取效果图编辑编辑目录结构编辑html部分H5神