本文分享自华为云社区《基于OpenTelemetry实现Java微服务调用链跟踪》,作者: 可以交个朋友。

一 背景

随着业务的发展,所有的系统都会走向微服务化体系,微服务进行拆分后,服务的依赖关系变得复杂,如果出现了错误和异常,定位的过程将会变得复杂,一个请求可能需要调用很多个服务,所以微服务架构中,分布式链路跟踪的实现至关重要,去跟进一个请求到底有哪些服务参与,参与的顺序又是怎样的,从而达到每个请求的步骤清晰可见。如何快速查询整个请求链路上的信息并呈现出来是解决排查问题复杂度的根本方法。

二 简介

Java 是世界上最流行的编程语言之一,很多大小项目都是通过Java进行微服务的开发来实现。
本篇博客将以springboot微服务为例,通过使用opentelemetry-java SDK 进行自动埋点以代码无侵入的方式实现微服务的分布式跟踪能力。

三 实践演示

demo项目一共3个service:foo-svc、bar-svc 、loo-svc 。
项目源码可前往:https://github.com/HFfleming/springboot-trace-demo/tree/autoconfigure

访问效果如下:

3.1 前提条件

已创建k8s 集群,可使用CCE集群平台作为基础环境。

k8s 集群中已安装opentelemetry-collector组件

k8s 集群中已安装jaeger作为分布式跟踪数据展示的平台

3.2 集成opentelemetry-java-instrumentation

OpenTelemetry 提供了 Java agent(opentelemetry-java-instrumentation)。当附加到应用程序中时,它会修改各种流行库和框架的字节码以捕获遥测数据。可以以多种格式导出遥测数据。还可以通过命令行参数或环境变量配置代理和导出器。最终结果是无需更改代码即可从 Java 应用程序收集遥测数据。

下载otel-java jar包并添加到容器镜像中

前往官方仓库 https://github.com/open-telemetry/opentelemetry-java-instrumentation 下载opentelemetry-javaagent.jar

通过环境变量配置java agent和otlp导出器

  • 通过环境变量的形式配置java agent:ENV JAVA_TOOL_OPTIONS="-javaagent:/usr/app/opentelemetry-javaagent.jar"

  • 服务名称: ENV OTEL_SERVICE_NAME="foo-svc"

  • 使用otlp协议的导出器:ENV OTEL_TRACES_EXPORTER="otlp"

  • 关闭java agent的指标 otlp导出器: ENV OTEL_METRICS_EXPORTER="none"

  • 关闭java agent的日志 otlp导出器: ENV OTEL_LOGS_EXPORTER="none"

  • 指定OTLP导出器的端点,跨ns的场景下建议写上otel的ns:ENV OTEL_EXPORTER_OTLP_ENDPOINT="http://opentelemetry-collector.tracing.svc.cluster.local:4317"

    除了环境变量的形式,也可通过jvm参数形式进行agent和导出器的配置。
    详细配置或者欲开启更多导出信息可参考: https://github.com/open-telemetry/opentelemetry-java/tree/main/sdk-extensions/autoconfigure

容器镜像制作

建议重新制作镜像,将opentelemetry-javaagent等otlp基础配置打包在镜像中。后续如果有变动,也可通过deployment中env字段进行修改覆盖。

镜像Dockerfile文件可参照如下:

#基于官方的Maven镜像
FROM maven:3.8.7-openjdk-18-slim AS build #将本地代码复制到Docker容器中的 /usr/src/app 目录下
COPY src /usr/src/foo-app/src
COPY pom.xml /usr/src/foo-app
COPY opentelemetry-javaagent.jar /usr/src/foo-app # 在容器的 /usr/src//foo-app 目录下,运行mvn clean package 命令,构建项目
RUN mvn -f /usr/src/foo-app/pom.xml clean package # 使用官方的openjdk 镜像作为基础镜像
FROM openjdk:19-jdk-slim # 将打包生成的jar文件复制到容器中
COPY --from=build /usr/src/foo-app/target/*.jar /usr/app/foo-app.jar
COPY --from=build /usr/src/foo-app/opentelemetry-javaagent.jar /usr/app/opentelemetry-javaagent.jar # 声明服务运行在8080端口
EXPOSE 8080 # 通过环境变量的形式配置java agent并且通过环境变量传递配置属性
ENV JAVA_TOOL_OPTIONS="-javaagent:/usr/app/opentelemetry-javaagent.jar"
# 服务的k8s servicename
ENV OTEL_SERVICE_NAME="foo-svc"
# 使用的是otlp协议的导出器
ENV OTEL_TRACES_EXPORTER="otlp"
# 关闭java agent的指标 otlp导出器
ENV OTEL_METRICS_EXPORTER="none"
## 关闭java agent的日志 otlp导出器
ENV OTEL_LOGS_EXPORTER="none"
# 指定OTLP导出器的端点,跨ns的场景下建议写上otel的ns
ENV OTEL_EXPORTER_OTLP_ENDPOINT="http://opentelemetry-collector.tracing.svc.cluster.local:4317" #指定docker容器的启动命令
ENTRYPOINT ["java", "-jar","/usr/app/foo-app.jar"]

镜像推送至镜像仓库,可使用SWR容器镜像仓库

docker build 构建完镜像后,然后docker push 至镜像仓库。
本人demo项目镜像如下,可供读者调试使用:
foo-svc: swr.cn-north-4.myhuaweicloud.com/k8s-solution/foo-svc:v2
bar-svc: swr.cn-north-4.myhuaweicloud.com/k8s-solution/bar-svc:v2
loo-svc: swr.cn-north-4.myhuaweicloud.com/k8s-solution/loo-svc:v2

在k8s集群中部署demo项目

其中loadgenerator服务是个客户端工具用于访问demo项目。访问信息如下:

相比之前没有集成opentelemetry-javaagent.jar ,访问信息请求头多了traceparent信息,很明显该信息就是分布式跟踪所需要使用到的

3.3 OpenTelemetry配置遥测数据的接受和导出

在上述环境变量中,通过otlp-grpc协议进行java微服务遥测数据导出的。所以在opentelemetry-collector中的receivers接收器配置中需要配置otlp grpc规则进行数据的接受:

receivers:
otlp:
protocols:
grpc:
endpoint: ${env:MY_POD_IP}:4317

otel接受到数据后,需要将数据处理后进行导出。导出后端可以是jaeger,通过jaeger进行分布式跟踪数据的展示,需要需要在opentelemery-collector中配置exporter导出器

exporters:
debug: {} #导出器配置log,可记录导出行为
otlp:
endpoint: jaeger-collector.hu.svc.cluster.local:4317 #jaeger的otlp-grpc端口
tls:
insecure: true

需要注意此处导出器后端jaeger使用的协议为otlp,如果jaeger-collector service未配置该端口,则会导出失败,建议检查jaeger相关service的配置。

- name: otlp-grpc
port: 4317
protocol: TCP
targetPort: 4317

通过pipeline启用otel采集器中配置的各种组件。上面配置了接收器和导出器,如果不在pipeline中声明,则不会启用该组件。启用方式参考:

service: # 用于根据接收器、处理器、导出器和扩展部分中的配置来配置收集器中启用的组件
extensions:
- health_check
pipelines:
traces:
exporters:
- debug
- otlp
processors:
- memory_limiter
- batch
receivers:
- otlp

完整配置参考如下,这些配置以configmap形式挂载到otel-collector容器中使用。

apiVersion: v1
kind: ConfigMap
metadata:
name: opentelemetry-collector
namespace: tracing
data:
relay: |
exporters:
debug: {}
otlp:
endpoint: jaeger-collector.hu.svc.cluster.local:4317
tls:
insecure: true
extensions:
health_check:
endpoint: ${env:MY_POD_IP}:13133 processors:
batch: {}
memory_limiter:
check_interval: 5s
limit_percentage: 80
spike_limit_percentage: 25 receivers:
otlp:
protocols:
grpc:
endpoint: ${env:MY_POD_IP}:4317 service:
extensions:
- health_check
pipelines:
traces:
exporters:
- debug
- otlp
processors:
- memory_limiter
- batch
receivers:
- otlp telemetry:
metrics:
address: ${env:MY_POD_IP}:8888

配置更新后,重启otel-collector容器。查看otel容器日志可以看到otel已经以配置的规则进行工作。

3.4 Jaeger查看调用链跟踪数据

访问jaeger UI,UI端口为16686。可以看到jaeger已经接收到trace信息,目前已有4条trace,每条trace均有8个span信息。

查看详细span信息,不仅可以看到服务级别的调用,还能看到方法级别的调用,以及方法级别的耗时。

点击关注,第一时间了解华为云新鲜技术~

基于OpenTelemetry实现Java微服务调用链跟踪的更多相关文章

  1. 第四模块 :微服务调用链监控CAT架构和实践

    采样率:每一个请求为都进行记录,或者100次请求为记录50次 各个开源框架都满足opentracing的标准,只要使用opentracing标准埋点的客户端,可以使用不同的客户端去展示,opentra ...

  2. 微服务架构 | 10.1 使用 Sleuth 追踪服务调用链

    目录 前言 1. Sleuth 基础知识 1.1 Sleuth 原理 2. 在服务中使用 Sleuth 追踪 2.1 引入 pom.xml 依赖文件 2.2 查看日志信息 最后 前言 参考资料: &l ...

  3. 多云架构下,JAVA微服务技术选型实例解析

    [摘要] 本文介绍了基于开源自建和适配云厂商开发框架两种构建多云架构的思路,以及这些思路的优缺点. 微服务生态 微服务生态本质上是一种微服务架构模式的实现,包括微服务开发SDK,以及微服务基础设施. ...

  4. 基于Spring Cloud的微服务入门教程

    (本教程的原地址发布在本人的简书上:http://www.jianshu.com/p/947d57d042e7,若各位看官有什么问题或不同看法请在这里或简书留言,谢谢!) 本人也是前段时间才开始接触S ...

  5. 干货|基于 Spring Cloud 的微服务落地

    转自 微服务架构模式的核心在于如何识别服务的边界,设计出合理的微服务.但如果要将微服务架构运用到生产项目上,并且能够发挥该架构模式的重要作用,则需要微服务框架的支持. 在Java生态圈,目前使用较多的 ...

  6. 基于Spring Cloud的微服务落地

    微服务架构模式的核心在于如何识别服务的边界,设计出合理的微服务.但如果要将微服务架构运用到生产项目上,并且能够发挥该架构模式的重要作用,则需要微服务框架的支持. 在Java生态圈,目前使用较多的微服务 ...

  7. Java微服务框架一览

    引言:本文首先简单介绍了微服务的概念以及使用微服务所能带来的优势,然后结合实例介绍了几个常见的Java微服务框架. 微服务在开发领域的应用越来越广泛,因为开发人员致力于创建更大.更复杂的应用程序,而这 ...

  8. Java微服务(二):服务消费者与提供者搭建

    本文接着上一篇写的<Java微服务(一):dubbo-admin控制台的使用>,上篇文章介绍了docker,zookeeper环境的安装,并参考dubbo官网演示了dubbo-admin控 ...

  9. Java微服务(二):负载均衡、序列化、熔断

    本文接着上一篇写的<Java微服务(二):服务消费者与提供者搭建>,上一篇文章主要讲述了消费者与服务者的搭建与简单的实现.其中重点需要注意配置文件中的几个坑. 本章节介绍一些零散的内容:服 ...

  10. 智能家居巨头 Aqara 基于 KubeSphere 打造物联网微服务平台

    背景 从传统运维到容器化的 Docker Swarm 编排,从 Docker Swarm 转向 Kubernetes,然后在 Kubernetes 运行 SpringCloud 微服务全家桶,到最终拥 ...

随机推荐

  1. 部署开源项目管理工具focalboard

    前言 focalboard是一款开源项目管理工具,类似Jira.Trello.官网地址 组件 版本 说明 Debian 12.1 操作系统 docker 20.10.7 容器运行时 docker-co ...

  2. 【linux】Linux内核结构体--kfifo 环状缓冲区

    1.前言 最近项目中用到一个环形缓冲区(ring buffer),代码是由linux内核的kfifo改过来的.缓冲区在文件系统中经常用到,通过缓冲区缓解cpu读写内存和读写磁盘的速度.例如一个进程A产 ...

  3. 远程连接-ssh

  4. [转帖]Day64_Kafka(二)

    第二讲 Kafka架构 课程大纲 课程内容 学习效果 掌握目标 Kafka架构 Kafka就 掌握 Kafka ack Exactly once Kafka log Kafka log 掌握 Kafk ...

  5. [转帖]redis进程绑定指定的CPU核

    文章系转载,便于分类和归纳,源文地址:https://blog.csdn.net/youlinhuanyan/article/details/99671878 1)查看某服务的pid $ ps -au ...

  6. [转帖]将nginx.conf文件的内容拆分成多个

    nginx的如果有多个server模块都配置在同一个nginx.conf文件会显得比较臃肿,后续维护起来也会比较困难,所以可以将内容写入到多个配置文件中然后在nginx.conf文件中通过includ ...

  7. 编译打包rabbitmq然后一键部署的简单方法

    摘要 之前总结过一版,但是感觉不太全面 想着本次能够将使用中遇到的问题总结一下. 所以本次是第二版 介质下载 rabbitmq 不区分介质的打包文件 rabbitmq-server-generic-u ...

  8. 银河麒麟(Ubuntu)无法上网问题的解决方法

    最近部门借了几台银河麒麟的服务器. 因为有特殊用途, 不允许连接互联网,所以没办法只能搭建一个小的局域网进行处理. 但是发现在搭建过程中遇到了一些坑, 之前协助同事解决odoo问题时也遇到过, 当时本 ...

  9. FM的一种简易解调方式

    理论来源 <高低频电路设计与制作> 铃木雅臣 著.这位作者的书写的都不错 电路图 模拟思路 设输入信号为 \[s(t) = \sin(w_0 t + \Delta w\int_{- \in ...

  10. 基于密码学的身份混淆系统 -- idmix

    简介 Hyperledger Fabric的Idemix是一个基于密码学的身份混淆系统,它提供了一种在区块链网络中实现用户隐私的方法.Idemix的主要特性是它的零知识证明系统,这是一种允许用户证明他 ...