云原生架构下微服务接入 SkyWalking 最佳实践

背景

本文介绍在 Kubernetes 集群中,如何通过 Sidecar 模式为 Java 应用无侵入式部署 SkyWalking 探针,并利用 DataKit 内置的 SkyWalking 采集器,一站式收集链路数据(Trace)与应用日志(Log),最终在观测云平台实现强大的链路与日志联动查询,全面提升可观测性能力。

部署 SkyWalking 探针

SkyWalking Agent Sidecar 容器

该容器负责提供 skywalking-agent.jar 及其配置文件。

  • 环境变量: 配置应用名(SW_AGENT_NAME
  • Volume 挂载: 将 Agent 目录挂载到共享 Volume
  • Sidecar 容器镜像 dockerfile:
bash 复制代码
FROM alpine:3.14

  

# 下载SkyWalking探针

RUN wget -O /tmp/skywalking-agent.tar.gz \

    https://archive.apache.org/dist/skywalking/java-agent/8.8.0/apache-skywalking-java-agent-8.8.0.tgz \

    && tar -zxvf /tmp/skywalking-agent.tar.gz -C / \

    && mv /skywalking-agent /agent \

    && rm /tmp/skywalking-agent.tar.gz

  

# 复制启动脚本

COPY entrypoint.sh /entrypoint.sh

RUN chmod +x /entrypoint.sh

  

ENTRYPOINT ["/entrypoint.sh"]

entrypoint.sh

bash 复制代码
#!/bin/sh

  

# 创建配置目录

mkdir -p /agent/config

  

# 动态生成agent.config

cat <<EOF > /agent/config/agent.config

# 服务名由环境变量传入

agent.service_name=${SW_AGENT_NAME:demo}

# DataKit地址由环境变量传入

collector.backend_service=${SW_AGENT_COLLECTOR_BACKEND_SERVICES:datakit-service.datakit.svc.cluster.local:11800}

EOF

  

# 将探针复制到共享卷

cp -r /agent/* /sw-agent/

  

# 保持容器运行

tail -f /dev/null

业务容器

  • 无需修改镜像: 业务镜像本身无需包含任何 SkyWalking 依赖。
  • JVM 参数注入: 通过 JAVA_TOOL_OPTIONS 环境变量,指向共享 Volume 中的 skywalking-agent.jar。
  • Volume 挂载: 同样挂载共享 Volume,以访问其中的 Agent 文件。

业务 yaml

yaml 复制代码
apiVersion: apps/v1

kind: Deployment

metadata:

  name: service-b

spec:

  replicas: 1

  selector:

    matchLabels:

      app: service-b

  template:

    metadata:

      labels:

        app: service-b

    spec:

      volumes:

        - name: sw-agent

          emptyDir: {}

      containers:

        # 主应用容器

        - name: service-b-app

          image: zhaoje/service-b:sw3.0

          ports:

            - containerPort: 8081

          volumeMounts:

            - name: sw-agent

              mountPath: /sw-agent

          env:

            - name: JAVA_TOOL_OPTIONS

              value: "-javaagent:/sw-agent/skywalking-agent.jar"

        # SkyWalking边车容器

        - name: sw-agent-sidecar

          image: xxx/sw-agent-sidecar:8.8.2

          env:

            - name: SW_AGENT_NAME

              value: "service-b"

          volumeMounts:

            - name: sw-agent

              mountPath: /sw-agent

---

apiVersion: v1

kind: Service

metadata:

  name: service-b

spec:

  #type: NodePort

  selector:

    app: service-b

  ports:

    - protocol: TCP

      port: 8081

      targetPort: 8080

应用日志关联 Trace

本最佳实践以 log4j2 示例,将 toolkit 依赖包添加到 maven 或者 gradle 中:

xml 复制代码
         <dependency>

            <groupId>org.apache.skywalking</groupId>

            <artifactId>apm-toolkit-log4j-2.x</artifactId>

            <version>8.8.0</version> 

        </dependency>

        <dependency>

            <groupId>org.apache.skywalking</groupId>

            <artifactId>apm-toolkit-trace</artifactId>

            <version>8.8.0</version>

        </dependency>
  • apm-toolkit-log4j-2.x: 这是最关键的依赖。它为 Log4j2 这个日志框架提供了扩展。具体来说,它提供了一个特殊的 %tid 模式转换器(Pattern Layout Converter)。正是因为有了这个依赖,您才能在后面的 log4j2.xml 配置中使用 [%tid] 来输出 Trace ID。
  • apm-toolkit-trace: 这个依赖提供了一些有用的 API,例如 TraceContext.traceId() 用于在代码中手动获取当前链路的 Trace ID。虽然很多功能由探针自动完成,但如果您想在业务代码中主动操作追踪上下文,就需要它。

并在服务目录下新增 log4j2.xml 定义输出格式,在示例中的路径是:/root/service-a/src/main/resources

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>

<Configuration status="WARN">

    <Appenders>

        <!-- 控制台输出 -->

        <Console name="Console" target="SYSTEM_OUT">

            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%tid] [%thread] %-5level %logger{36} - %msg%n"/>

        </Console>

        <!-- SkyWalking gRPC日志输出 -->

        <GRPCLogClientAppender name="GrpcLog">

            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%tid] [%thread] %-5level %logger{36} - %msg%n"/>

        </GRPCLogClientAppender>

    </Appenders>

    <Loggers>

        <!-- 设置Spring框架日志级别 -->

        <Logger name="org.springframework" level="WARN" additivity="false">

            <AppenderRef ref="Console"/>

            <AppenderRef ref="GrpcLog"/>

        </Logger>

        <Root level="INFO">

            <AppenderRef ref="Console"/>

            <AppenderRef ref="GrpcLog"/>

        </Root>

    </Loggers>

</Configuration>

DataKit 开启 SkyWalking 采集器

部署配置 DataKit

在观测云控制台点击「集成」-「DataKit」-「Kubernetes」,运行脚本下载。

arduino 复制代码
wget https://static.guance.com/datakit/datakit.yaml

开启 SkyWalking 采集器

在 volumeMounts 中添加

yaml 复制代码
        - mountPath: /usr/local/datakit/conf.d/skywalking/skywalking.conf

          name: datakit-conf

          subPath: skywalking.conf

          readOnly: true

在 configmap 中增加 SkyWalking 配置

ini 复制代码
apiVersion: v1

kind: ConfigMap

metadata:

  name: datakit-conf

  namespace: datakit

data:

    skywalking.conf: |-

      [inputs.skywalking]

       endpoints = ["/v3/trace", "/v3/metric", "/v3/logging", "/v3/profiling"]

       address = "0.0.0.0:11800"

观测云

可以看到链路数据正常上报的观测云空间

链路和日志也通过 trace_id 串联起来

在日志页面也可以反向查询链路数据

总结

通过本文介绍的 Sidecar 模式与 DataKit 相结合的方案,我们成功实现了:

  • 轻量级集成: 以非侵入方式为集群 Java 应用快速赋予了链路追踪能力。
  • 架构简化: 利用 DataKit 替代了 SkyWalking OAP + Storage 的复杂组件,降低了运维成本。
  • 数据融合: 最终在观测云平台上实现了链路追踪数据与应用日志数据的无缝关联与联动查询,形成了完整的可观测性闭环。
相关推荐
FQNmxDG4S19 小时前
Java多线程编程:Thread与Runnable的并发控制
java·开发语言
虹科网络安全19 小时前
艾体宝干货|数据复制详解:类型、原理与适用场景
java·开发语言·数据库
axng pmje20 小时前
Java语法进阶
java·开发语言·jvm
rKWP8gKv720 小时前
Java微服务性能监控:Prometheus与Grafana集成方案
java·微服务·prometheus
老前端的功夫20 小时前
【Java从入门到入土】28:Stream API:告别for循环的新时代
java·开发语言·python
qq_4352879220 小时前
第9章 夸父逐日与后羿射日:死循环与进程终止?十个太阳同时值班的并行冲突
java·开发语言·git·死循环·进程终止·并行冲突·夸父逐日
小江的记录本20 小时前
【Kafka核心】架构模型:Producer、Broker、Consumer、Consumer Group、Topic、Partition、Replica
java·数据库·分布式·后端·搜索引擎·架构·kafka
yaoxin52112321 小时前
397. Java 文件操作基础 - 创建常规文件与临时文件
java·开发语言·python
极客先躯1 天前
高级java每日一道面试题-2025年11月24日-容器与虚拟化题[Dockerj]-runc 的作用是什么?
java·oci 的命令行工具·最小可用·无守护进程·完全标准·创建容器的核心流程·runc 核心职责思维导图
用户60648767188961 天前
AI 抢不走的技能:用 Claude API 构建自动化工作流实战
java