文档首页
MySQL Connector/J 开发人员指南
相关文档 下载本手册
PDF (US Ltr) - 1.2Mb
PDF (A4) - 1.2Mb


MySQL Connector/J 开发人员指南  /  使用 Connector/J 与 OpenTelemetry

第 13 章 使用 Connector/J 与 OpenTelemetry

OpenTelemetry 是一套 API、库、代理和检测工具,用于提供应用程序及其相互交互的可观察性。它使开发人员能够检测其代码,以便他们可以导出可观察性数据,包括跟踪、指标和日志,从而提高分析、调试和测试的粒度。

OpenTelemetry 项目为 JDBC 库提供了自动检测功能。但是,在分布式跟踪方面,自动检测无法将上下文传播到数据库层,导致跟踪链断裂。此外,自动检测仅适用于 JDBC 检测的可见层,而排除了值得跟踪的任何内部操作。

MySQL Enterprise Server 8.4.0 具有以 OpenTelemetry 格式收集服务器操作可观察性数据的功能(有关详细信息,请参阅 遥测)。该功能由 component_telemetry 支持。MySQL Connector/J 8.4.0 引入了客户端对应功能,它能够将上下文传播到其连接到的 MySQL 服务器,并允许对应用程序堆栈进行更完整的可观察性。

使用 Connector/J 的应用程序如果希望启用 OpenTelemetry 跟踪,需要以下第三方库

Connector/J 连接属性 openTelemetry 控制如何在每个连接的基础上处理可观察性数据生成。此选项接受以下值

  • REQUIRED:运行时必须有 OpenTelemetry 库可用,否则连接到 MySQL 服务器将失败。请注意,仅 opentelemtry-api 库不会生成任何输出跟踪。

  • PREFERRED:启用生成 OpenTelemetry 检测,前提是在运行时有 OpenTelemetry 库可用;如果库不可用,则会发出警告。

  • DISABLED:关闭 Connector/J 生成 OpenTelemetry 检测。但是,这不会阻止外部检测方式,例如 OpenTelemetry Java 代理提供的自动检测。

未设置该属性的值等同于将其设置为 PREFERRED,只是在运行时没有 OpenTelemetry 库可用时不会发出警告。

请注意,MySQL Connector/J 不提供任何配置其自身 OpenTelemetry 导出程序的方法,它完全依赖于调用应用程序进行导出程序配置。

以下是关于如何使用 OpenTelemetry 的演示。假设客户端应用程序、MySQL 服务器和可观察性后端都在同一台机器上运行。还假设 component_telemetry 已启用并在 MySQL 服务器上正确配置。为了简单起见,使用 Java 代理。还使用了 opentelemetry-instrumentation-annotations 库,因此无需在示例类中编写任何 OpenTelemetry 代码。

这个简单的演示包含一个类 OTelDemo,它创建一个连接到 Sakila 数据库 并执行一个 SQL SELECT 语句,该语句从 film 表中返回五行。该演示的目的是生成一系列跟踪,而不是生成任何实际有用的内容。以下是源文件 src/demo/OTelDemo.java 的内容

package demo;
import java.sql.*;
import io.opentelemetry.instrumentation.annotations.WithSpan;
public class OTelDemo {
    public static void main(String[] args) throws Exception {
        listFiveFilms();
    }
    @WithSpan
    private static void listFiveFilms() throws Exception {
        try (Connection conn = DriverManager.getConnection("jdbc:mysql://johndoe:s3cr3t@localhost:3306/sakila")) {
            Statement stmt = conn.createStatement();
            ResultSet rs = stmt.executeQuery("SELECT * FROM film LIMIT 5");
            while (rs.next()) {
                System.out.println(rs.getString(2));
            }
        }
    }
}

通过注释 @WithSpan,将在应用程序代码中创建将观察到的顶级跟踪。此跟踪成为 JDBC 驱动程序中创建的任何后续跨度的当前上下文(父级)。随后,通过与执行的命令一起传播上下文,驱动程序创建的跟踪成为 MySQL 服务器中创建的跨度的父级。

可以通过发出以下命令来编译代码

$ javac -classpath "lib/*" -d bin src/demo/OTelDemo.java

在运行演示之前,请使用例如 Jaeger 设置可观察性后端。然后,您可以使用以下命令执行代码

$ java -javaagent:agent/opentelemetry-javaagent.jar \
  -Dotel.traces.exporter=jaeger \
  -Dotel.metrics.exporter=none \
  -Dotel.service.name=OTelDemo \
  -Dotel.instrumentation.common.default-enabled=false \
  -Dotel.instrumentation.opentelemetry-api.enabled=true \
  -Dotel.instrumentation.opentelemetry-instrumentation-annotations.enabled=true \
  -classpath "bin:lib/*" \
  demo.OTelDemo
 [otel.javaagent 2024-04-12 16:10:32:140 +0100]
 [main] INFO io.opentelemetry.javaagent.tooling.VersionLogger - opentelemetry-javaagent - version: 1.32.0
 ACADEMY DINOSAUR
 ACE GOLDFINGER
 ADAPTATION HOLES
 AFFAIR PREJUDICE
 AFRICAN EGG

现在,您可以在 Web 浏览器中打开 Jaeger 后端,并搜索 OTelDemo 服务的跟踪。

MySQL 中的分布式跟踪仅限于语句执行。此限制来自以下事实:上下文传播是通过 查询属性 实现的,并且仅支持查询执行。在运行时,服务器也会为其他操作生成跨度。这些跨度也可以在可观察性后端中看到,但它们与客户端应用程序或库启动的任何跟踪都没有关联。同样,Connector/J 创建的跨度,不会生成服务器命令,或者生成不支持查询属性的命令,在跟踪图中显示为终端节点。例如,PING 命令操作。尽管如此,服务器仍然会为相应操作生成一个跨度,只是它看起来与源跟踪没有关联。然而,服务器仍然会为相应操作生成一个跨度,只是它看起来与源跟踪没有关联。