在快速发展的软件开发领域,尤其是在云原生领域,DevOps 和 SRE 团队正日益成为应用程序稳定性和增长的重要合作伙伴。
DevOps 工程师不断优化软件交付,而 SRE 团队则充当应用程序可靠性、可扩展性和顶级性能的管理者。挑战是什么?这些团队需要一个尖端的可观测性解决方案,该解决方案涵盖全栈洞察,使他们能够在潜在的破坏演变成运营挑战之前快速管理、监控和纠正这些破坏。
我们现代分布式软件生态系统中的可观测性不仅仅是简单的监控,它还需要无限的数据收集、精确的处理以及将这些数据关联到可操作的洞察中。然而,实现这种整体视图的道路上布满了障碍,从处理版本不兼容到与限制性的专有代码作斗争。
了解 OpenTelemetry (OTel),它为采用者带来以下好处
- 使用 OTel 摆脱供应商的约束,摆脱供应商锁定并确保一流的可观测性。
- 查看统一的日志、指标和跟踪的和谐结合,以提供完整的系统视图。
- 通过更丰富和增强的检测来改进您的应用程序监督。
- 拥抱向后兼容性的好处,以保护您先前的检测投资。
- 以简单的学习曲线开始 OpenTelemetry 之旅,简化入门和可扩展性。
- 依靠久经考验的、面向未来的标准来增强您对每一项投资的信心。
在本博客中,我们将探讨如何使用 Docker 在 Java 应用程序中使用 自动检测,而无需重构应用程序代码的任何部分。我们将使用一个名为 Elastiflix 的应用程序,它可以帮助以简单的方式突出自动检测。
应用程序、先决条件和配置
我们在此博客中使用的应用程序名为 Elastiflix,这是一个电影流媒体应用程序。它由用 .NET、NodeJS、Go 和 Python 编写的多个微服务组成。
在我们检测示例应用程序之前,我们首先需要了解 Elastic 如何接收遥测数据。
Elastic 可观测性的所有 APM 功能都可用于 OTel 数据。其中一些包括
- 服务地图
- 服务详细信息(延迟、吞吐量、失败的事务)
- 服务之间的依赖关系,分布式跟踪
- 事务(跟踪)
- 机器学习 (ML) 相关性
- 日志关联
除了 Elastic 的 APM 和遥测数据的统一视图外,您还可以使用 Elastic 强大的机器学习功能来减少分析和警报,从而帮助减少 MTTR。
先决条件
- 一个 Elastic Cloud 帐户 — 立即注册。
- 一个 Elastiflix 演示应用程序的克隆,或者您自己的 Java 应用程序
- Docker 的基本知识 — 可能会安装 Docker Desktop
- Java 的基本知识
查看示例源代码
完整的源代码,包括此博客中使用的 Dockerfile,可以在 GitHub 上找到。该存储库还包含相同但没有检测的应用程序。这允许您比较每个文件并查看差异。
以下步骤将向您展示如何检测此应用程序并在命令行或 Docker 中运行它。如果您对更完整的 OTel 示例感兴趣,请查看 此处的 docker-compose 文件,它将启动整个项目。
逐步指南
第 0 步。登录您的 Elastic Cloud 帐户
此博客假设您拥有一个 Elastic Cloud 帐户 — 如果没有,请按照 在 Elastic Cloud 上开始使用的说明进行操作。
第 1 步。为 Java 服务配置自动检测
我们将使用 Elastiflix 演示应用程序中的 Java 服务进行自动检测。
我们将使用 Elastiflix 中的以下服务
Elastiflix/java-favorite-otel-auto
根据OpenTelemetry Java 自动检测文档和文档,您只需安装相应的 Java 包即可。
创建一个本地 OTel 目录以下载 OpenTelemetry Java 代理。下载 opentelemetry-javaagent.jar。
>mkdir /otel
>curl -L https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar –output /otel/opentelemetry-javaagent.jar
如果您要在命令行上运行该服务,则可以使用以下命令
java -javaagent:/otel/opentelemetry-javaagent.jar \
-jar /usr/src/app/target/favorite-0.0.1-SNAPSHOT.jar --server.port=5000
对于我们的应用程序,我们将把它作为 Dockerfile 的一部分来完成。
Dockerfile
Start with a base image containing Java runtime
FROM maven:3.8.2-openjdk-17-slim as build
# Make port 8080 available to the world outside this container
EXPOSE 5000
# Change to the app directory
WORKDIR /usr/src/app
# Copy the local code to the container
COPY . .
# Build the application
RUN mvn clean install
USER root
RUN apt-get update && apt-get install -y zip curl
RUN mkdir /otel
RUN curl -L -o /otel/opentelemetry-javaagent.jar https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v1.28.0/opentelemetry-javaagent.jar
COPY start.sh /start.sh
RUN chmod +x /start.sh
ENTRYPOINT ["/start.sh"]
第 2 步。使用环境变量运行 Docker 镜像
如 OTEL Java 文档中所述,我们将使用环境变量并传入配置值,以使其能够与 Elastic 可观测性的 APM 服务器连接。
由于 Elastic 本地接受 OTLP,我们只需要提供 OTEL 导出器需要发送数据的端点和身份验证,以及一些其他环境变量。
获取 Elastic Cloud 变量
您可以从 Kibana 中复制端点和令牌,路径如下
您将需要复制以下环境变量
OTEL_EXPORTER_OTLP_ENDPOINT
OTEL_EXPORTER_OTLP_HEADERS
构建 Docker 镜像
docker build -t java-otel-auto-image .
运行 Docker 镜像
docker run \
-e OTEL_EXPORTER_OTLP_ENDPOINT="REPLACE WITH OTEL_EXPORTER_OTLP_ENDPOINT" \
-e ELASTIC_APM_SECRET_TOKEN="REPLACE WITH THE BIT AFTER Authorization=Bearer " \
-e OTEL_RESOURCE_ATTRIBUTES="service.version=1.0,deployment.environment=production" \
-e OTEL_SERVICE_NAME="java-favorite-otel-auto" \
-p 5000:5000 \
java-otel-auto-image
您现在可以发出一些请求以生成跟踪数据。请注意,这些请求预计会返回错误,因为此服务依赖于您当前未运行的 Redis 连接。如前所述,您可以在 此处找到使用 docker-compose 的更完整示例。
curl localhost:5000/favorites
# or alternatively issue a request every second
while true; do curl "localhost:5000/favorites"; sleep 1; done;
第 3 步:在 Elastic APM 中浏览跟踪和日志
一旦您启动并运行了此功能,您就可以 ping 检测到的服务的端点(在我们的示例中,这是 /favorites),您应该会在 Elastic APM 中看到该应用程序,如下所示
它将首先跟踪 SRE 需要注意的吞吐量和延迟关键指标。
深入研究,我们可以看到所有事务的概述。
并查看特定事务
点击 Logs(日志),我们可以看到日志也被引入了。OTel Agent 将自动引入日志,并将其与跟踪关联起来。
这使您能够全面了解日志、指标和跟踪!
基本概念:APM 如何与 Java 协同工作
在我们继续之前,让我们先了解一些基本概念和术语。
- Java Agent(Java 代理): 这是一种可用于检测(或修改)Java 虚拟机 (JVM) 中类文件的字节码的工具。Java 代理可用于许多目的,如性能监控、日志记录、安全性等。
- Bytecode(字节码): 这是 Java 编译器从您的 Java 源代码生成的中间代码。此代码由 JVM 解释或即时编译,以生成可以执行的机器代码。
- Byte Buddy: Byte Buddy 是一个用于 Java 的代码生成和操作库。它用于在运行时创建、修改或调整 Java 类。在 Java 代理的上下文中,Byte Buddy 提供了一种强大而灵活的方式来修改字节码。Elastic APM Agent 和 OpenTelemetry Agent 都使用 Byte Buddy 作为底层工具。
现在,让我们谈谈如何使用 Byte Buddy 实现自动检测。
自动检测是指代理修改应用程序类字节码的过程,通常是为了插入监控代码。代理不会直接修改源代码,而是修改加载到 JVM 中的字节码。这是在 JVM 加载类时完成的,因此修改在运行时生效。
以下是对该过程的简化说明:
-
使用代理启动 JVM: 启动 Java 应用程序时,您可以使用 -javaagent 命令行选项指定 Java 代理。这将指示 JVM 在调用应用程序的 main 方法之前加载您的代理。此时,代理有机会设置类转换器。
-
使用 Byte Buddy 注册类文件转换器: 您的代理将使用 Byte Buddy 注册类文件转换器。转换器是一段代码,每次将类加载到 JVM 中时都会调用该代码。此转换器接收该类的字节码,并且可以在实际使用该类之前修改此字节码。
-
转换字节码: 当调用您的转换器时,它将使用 Byte Buddy 的 API 来修改字节码。Byte Buddy 允许您以高级、表达力强的方式指定转换,而不是手动编写复杂的字节码。例如,您可以指定要检测的特定类和该类中的方法,并提供一个“拦截器”来为该方法添加新的行为。
-
使用转换后的类: 一旦代理设置了其转换器,JVM 将像往常一样继续加载类。每次加载类时,都会调用您的转换器,从而允许它们修改字节码。然后,您的应用程序使用这些转换后的类,就好像它们是原始类一样,但它们现在具有您通过拦截器注入的额外行为。
本质上,使用 Byte Buddy 进行自动检测是在运行时修改 Java 类的行为,而无需直接更改源代码。这对于诸如日志记录、监控或安全性等跨领域问题尤其有用,因为它允许您将此代码集中在您的 Java 代理中,而不是将其分散在您的应用程序中。
总结
通过此 Dockerfile,您已将简单的 Java 应用程序转换为使用 OpenTelemetry 自动检测的应用程序。这将极大地帮助您了解应用程序性能、跟踪错误以及深入了解用户如何与您的软件交互。
请记住,可观测性是现代应用程序开发的关键方面,尤其是在分布式系统中。借助 OpenTelemetry 等工具,理解复杂系统变得容易一些。
在本博客中,我们讨论了以下内容:
- 如何使用 OpenTelemetry 自动检测 Java。
- 通过在 Docker 文件中使用标准命令,可以高效地完成自动检测,而无需在多个位置添加代码,从而实现可管理性。
- 通过使用 OpenTelemetry 及其对多种语言的支持,DevOps 和 SRE 团队可以轻松地自动检测其应用程序,从而立即深入了解整个应用程序堆栈的运行状况并缩短平均修复时间 (MTTR)。
由于 Elastic 可以支持多种数据摄取方法,无论是使用开源 OpenTelemetry 的自动检测还是使用其原生 APM 代理的手动检测,您都可以通过首先关注几个应用程序,然后在以后以最适合您业务需求的方式在您的应用程序中使用 OpenTelemetry 来计划迁移到 OTel。
开发者资源
- Elastiflix 应用程序,一个使用 OpenTelemetry 检测不同语言的指南
- Python:自动检测、手动检测
- Java:自动检测、手动检测
- Node.js:自动检测、手动检测
- .NET:自动检测、手动检测
- Go:手动检测
- 检测 OpenTelemetry 的最佳实践
通用配置和用例资源
- 在 Elastic 上使用 OpenTelemetry 的独立性
- 使用 Elastic 和 OpenTelemetry 在 Kubernetes 上实现现代可观测性和安全性
- 使用 OpenTelemetry 和 Elastic 进行日志记录的 3 种模型
- 将免费的开源 Elastic APM 作为 Elastic 可观测性部署的一部分添加
- 使用 Elastic 通过代码中的 OpenTelemetry API 捕获自定义指标
- 使用 OpenTelemetry 和 Elastic 使您的可观测性平台面向未来
- Elastic 可观测性:专为 Kubernetes、OpenTelemetry、Prometheus、Istio 等开放技术而构建
还没有 Elastic Cloud 帐户?注册 Elastic Cloud 并试用我上面讨论的自动检测功能。我很想获得您关于使用 Elastic 深入了解应用程序堆栈的经验的反馈。
本文中描述的任何特性或功能的发布和时间安排仍由 Elastic 自行决定。任何当前不可用的特性或功能可能不会按时交付或根本不交付。