Appearance
SkyWalking 极简教程
一、基础理论
1. 定位
- APM(应用性能监控)系统:集分布式追踪、服务拓扑、指标监控、性能剖析、告警于一体。
- 无侵入接入:通过 Java Agent 字节码增强自动埋点,无需修改业务代码。
- Apache 顶级开源项目,国内大规模落地,Spring Cloud / Kubernetes / Service Mesh 生态支持完善。
2. 核心架构
| 角色 | 说明 |
|---|---|
| Agent(探针) | 部署在应用侧,通过字节码增强自动采集 Trace / Metrics / Logs,经 gRPC 上报到 OAP。 |
| OAP(Observability Analysis Platform) | 后端分析平台,接收 Agent / Envoy 数据,流式分析后写入存储,提供查询 API。 |
| UI | 可视化界面,展示拓扑图、Trace、Dashboard、告警。 |
| Storage | 存储后端:H2(演示)、MySQL、Elasticsearch、BanyanDB(官方推荐)。 |
3. 核心概念
| 概念 | 说明 |
|---|---|
| Service | 服务,如 order-service;对应 Spring Cloud 的 spring.application.name。 |
| Service Instance | 服务实例,如 order-service 的一个 Pod 或进程。 |
| Endpoint | 端点,即接口路径,如 GET:/order/{id}。 |
| Trace | 一次完整请求的调用链。 |
| Span | 调用链中的单个工作单元(一次 HTTP 请求、一次 DB 查询等)。 |
| Segment | 一个 Trace 在单个进程中的所有 Span 集合;SkyWalking 按进程分段上报再拼接。 |
4. 核心原理
- 字节码增强:Agent 基于 ByteBuddy 框架,在 JVM 类加载期织入拦截代码,对主流框架自动埋点:
- HTTP:Spring MVC / Spring WebFlux / Gateway / Tomcat
- RPC:OpenFeign / Dubbo / gRPC
- DB:JDBC / MyBatis / JPA / Redis
- MQ:RocketMQ / Kafka / RabbitMQ
- 上下文传播:Agent 自动在当前线程上下文维护 Trace 信息,跨线程/跨进程通过 Carrier(Header)传播。
- gRPC 上报:Segment 完成后异步发送到 OAP,默认端口 11800。
- OAP 流式分析:接收原始 Segment,分析生成服务拓扑、慢端点排行、依赖关系图。
- 多维度展示:UI 提供拓扑图(服务依赖)、追踪(调用链瀑布流)、指标(CPU/内存/吞吐量/延迟)、性能剖析(方法级火焰图)。
无侵入拆解:
- 业务代码零改动,启动时加
-javaagent参数即可。- Agent 在类加载时修改字节码,在方法进入/退出时插入采集代码,业务无感知。
- 如需更细粒度控制,可通过 apm-toolkit 手动埋点。
5. 采样策略
| 配置 | 说明 |
|---|---|
agent.sample_n_per_3_secs | 每 3 秒最多采集 N 条 Trace;-1 表示全采集(开发用)。 |
agent.trace.ignore_path | 忽略特定路径,如静态资源 /health,/actuator/** 等。 |
plugin.xxx | 各插件级别开关,如关闭某个框架的追踪以减少开销。 |
生产建议:
sample_n_per_3_secs设置为-1或一个合理值(如 500),配合ignore_path过滤心跳/监控接口。
6. 与 Sleuth + Zipkin 对比
| 维度 | Spring Cloud Sleuth + Zipkin | Apache SkyWalking |
|---|---|---|
| 接入方式 | 引入依赖 + 配置 | 无侵入:-javaagent |
| 侵入性 | 低(需改依赖和配置) | 零侵入(纯启动参数) |
| 功能 | 链路追踪 + 耗时分析 | 链路 + 拓扑 + 指标 + 告警 + 性能剖析 + 日志 |
| 存储 | ES / MySQL / Cassandra | ES / BanyanDB / MySQL / H2 |
| 多语言 | Java 为主 | Java / Go / Node.js / Python / .NET |
| Spring 生态 | 原生集成 | 自动识别 Feign / Gateway / Nacos |
| 部署复杂度 | 简单(Jar/Docker) | 中等(OAP + UI + Storage) |
| 性能开销 | 较低 | 较低(通常 < 5%) |
选型建议:纯 Spring Cloud 内网微服务可选 Sleuth+Zipkin 快速上手;需要无侵入、拓扑大盘、生产级监控告警选 SkyWalking。
二、工作实践(复制即用)
1. OAP + UI + ES 部署(Docker Compose)
yaml
version: '3.8'
services:
elasticsearch:
image: elasticsearch:7.17.9
container_name: elasticsearch
environment:
- discovery.type=single-node
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
ports:
- "9200:9200"
oap:
image: apache/skywalking-oap-server:9.7.0
container_name: oap
depends_on:
- elasticsearch
environment:
SW_STORAGE: elasticsearch
SW_STORAGE_ES_CLUSTER_NODES: elasticsearch:9200
ports:
- "11800:11800" # Agent gRPC 上报
- "12800:12800" # REST API(UI 查询)
ui:
image: apache/skywalking-ui:9.7.0
container_name: ui
depends_on:
- oap
environment:
SW_OAP_ADDRESS: http://oap:12800
ports:
- "8080:8080"启动后访问:
http://localhost:8080,默认无密码。
2. Java Agent 接入 Spring Boot
下载 Agent
bash
wget https://archive.apache.org/dist/skywalking/java-agent/9.1.0/apache-skywalking-java-agent-9.1.0.tgz
tar -xzf apache-skywalking-java-agent-9.1.0.tgz启动参数
bash
java -javaagent:/opt/skywalking-agent/skywalking-agent.jar \
-Dskywalking.agent.service_name=order-service \
-Dskywalking.collector.backend_service=localhost:11800 \
-jar order-service.jar| 参数 | 说明 |
|---|---|
-javaagent | Agent Jar 绝对路径 |
agent.service_name | 服务名,对应 SkyWalking UI 中的 Service |
collector.backend_service | OAP gRPC 地址,默认 127.0.0.1:11800 |
IDE 开发测试(IntelliJ IDEA)
在 Run Configuration → VM options 中填入:
-javaagent:D:/tools/skywalking-agent/skywalking-agent.jar
-Dskywalking.agent.service_name=order-service
-Dskywalking.collector.backend_service=localhost:118003. 配置文件(agent.config)
skywalking-agent/config/agent.config 常用配置:
properties
# 服务名
agent.service_name=${SW_AGENT_NAME:order-service}
# OAP 地址
collector.backend_service=${SW_AGENT_COLLECTOR_BACKEND_SERVICES:127.0.0.1:11800}
# 日志文件名
agent.logging.file_name=${SW_LOGGING_FILE_NAME:skywalking-api.log}
# 采样:每 3 秒最多采集 -1 条(-1 表示不限,即全量;生产建议设具体值如 500)
agent.sample_n_per_3_secs=${SW_AGENT_SAMPLE:-1}
# 忽略路径(不追踪的 URL)
agent.trace.ignore_path=${SW_AGENT_TRACE_IGNORE_PATH:/health,/actuator/**,/eureka/**}
# 插件配置示例:关闭 Kafka 追踪
# plugin.kafka.trace_dsl=false环境变量优先级高于
agent.config;Docker/K8s 中建议用环境变量覆盖。
4. Spring Cloud Gateway 接入
SkyWalking Agent 自动支持 Spring Cloud Gateway(WebFlux 底层),无需额外依赖。
只需在 Gateway 启动时加同样的 -javaagent 参数,UI 中即可看到 Gateway 作为入口服务的完整拓扑。
⚠️ 注意:Agent 版本需 8.10+ 才完整支持 WebFlux / Gateway 的上下文传播。若版本过低,可能出现 Gateway 后链路断裂。
5. 日志中打印 SkyWalking TraceId
引入 toolkit
xml
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-logback-1.x</artifactId>
<version>9.1.0</version>
</dependency>logback-spring.xml
xml
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%tid] %logger{36} - %msg%n</pattern>
</layout>
</encoder>
</appender>
%tid是 SkyWalking 提供的扩展,无 Trace 时显示TID:N/A。
日志输出示例
2026-05-10 12:30:15.123 [http-nio-8081-exec-1] INFO [TID:a1b2c3d4e5f6g7h8.i9j0k1l2m3n4o5p6.1234567] c.e.o.controller.OrderController - 创建订单:userId=10016. 日志上报到 OAP(可选)
如果需要将业务日志关联到 Trace 并在 SkyWalking UI 中查看,使用 GRPCLogClientAppender:
xml
<appender name="SKYWALKING_LOG" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender">
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%tid] %logger{36} - %msg%n</pattern>
</layout>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="SKYWALKING_LOG"/>
</root>无需额外端口配置,日志经 Agent 已建立的 gRPC 连接上报到 OAP。
7. 手动埋点(apm-toolkit,可选)
Agent 已覆盖主流框架,但自定义逻辑如需单独追踪:
java
import org.apache.skywalking.apm.toolkit.trace.ActiveSpan;
import org.apache.skywalking.apm.toolkit.trace.TraceContext;
import org.apache.skywalking.apm.toolkit.trace.annotation.Trace;
@Service
public class BizService {
/**
* @Trace 标记的方法会自动创建一个 LocalSpan
*/
@Trace(operationName = "custom-complex-biz")
public void complexBiz() {
// 给当前 Span 打 Tag
ActiveSpan.tag("biz.type", "order-calculation");
ActiveSpan.tag("order.amount", "199.99");
// 记录错误信息
try {
riskyOperation();
} catch (Exception e) {
ActiveSpan.error(e, "业务异常:计算失败");
}
}
public void someMethod() {
// 获取当前 TraceId(可用于日志或返回给前端)
String traceId = TraceContext.traceId();
System.out.println("当前 TraceId: " + traceId);
}
}8. 告警规则简介
OAP 内置告警引擎,配置文件 config/alarm-settings.yml:
yaml
rules:
service_resp_time_rule:
metrics-name: service_resp_time
op: ">"
threshold: 1000
period: 10
count: 2
message: 服务 {name} 平均响应时间超过 1000ms,持续 2 个周期
silence-period: 5
service_sla_rule:
metrics-name: service_sla
op: "<"
threshold: 8000
period: 10
count: 2
message: 服务 {name} 成功率低于 80%| 字段 | 说明 |
|---|---|
metrics-name | 指标名:service_resp_time / service_sla / service_p99 等 |
op | 比较运算符:> / < / = |
threshold | 阈值 |
period | 检测周期(分钟) |
count | 触发告警的周期数 |
silence-period | 静默期(分钟),避免重复告警 |
告警可通过 Webhook 推送到企业微信 / 钉钉 / Slack。
三、核心速查表
| 概念/配置 | 说明 |
|---|---|
-javaagent | Agent 接入方式,无侵入 |
agent.service_name | 服务名,UI 中显示的 Service |
collector.backend_service | OAP gRPC 地址,默认 127.0.0.1:11800 |
agent.sample_n_per_3_secs | 采样率:-1 全量,生产建议设具体值 |
agent.trace.ignore_path | 忽略追踪的路径,如 /actuator/** |
apm-toolkit-logback-1.x | Logback 扩展包,支持 %tid 打印 TraceId |
TraceContext.traceId() | 代码中获取当前 TraceId |
@Trace | 手动埋点注解,自动创建 LocalSpan |
ActiveSpan.tag(key, value) | 给当前 Span 打标签 |
ActiveSpan.error(Throwable, msg) | 记录异常到当前 Span |
11800 | Agent → OAP 的 gRPC 端口 |
12800 | OAP REST API 端口(UI 查询) |
Segment | 一个进程内的 Span 集合 |
Service Topology | UI 中的服务依赖拓扑图 |
Endpoint | 接口级监控单元,如 GET:/order/{id} |
四、排错速查
| 现象 | 解决 |
|---|---|
| UI 看不到任何服务 | 1. 检查 Agent 与 OAP 版本是否匹配 2. 检查 collector.backend_service 地址和 11800 端口是否通3. 检查 agent.service_name 是否配置4. 检查 Agent 日志 skywalking-api.log 是否有连接错误 |
| Trace 链路断裂(下游无 Trace) | 1. 确认下游服务也加了 -javaagent2. 确认 Agent 版本支持跨服务传播的框架(如 Feign、RestTemplate) 3. 检查是否使用了自定义 HTTP 客户端未携带 SW Header(如 sw8) |
| Gateway 后链路断裂 | Agent 版本过低可能不支持 WebFlux;升级到 8.10+ 或 9.x |
日志中 %tid 显示 TID:N/A | 1. 确认引入了 apm-toolkit-logback-1.x2. 确认使用了 TraceIdPatternLogbackLayout3. 确认当前请求确实经过了 SkyWalking Agent 拦截(静态初始化或异步线程可能无上下文) |
| Agent 启动报错 / JVM 崩溃 | 1. 检查 JDK 版本(Agent 通常要求 JDK 8+) 2. 检查 -javaagent 路径是否正确3. 检查是否有其他字节码增强工具冲突(如多个 Agent) |
| 数据量太大 / OAP 内存高 | 1. 调整 agent.sample_n_per_3_secs 限制采样2. 增加 agent.trace.ignore_path 过滤心跳/监控/静态资源3. ES 集群扩容或调整 OAP JVM 参数 |
| 性能下降明显 | 1. 检查是否对高频短操作(如 Redis 大量 GET)全量追踪,可加 ignore_path 或关闭对应插件 2. 确认 Agent 版本为正式版而非 debug 版 3. 适当降低采样率 |
| 告警不触发 | 1. 检查 alarm-settings.yml 是否挂载到 OAP 容器2. 检查指标名和阈值是否正确 3. 检查 Webhook 地址是否可达 |
| Agent 与 Spring Boot 版本冲突 | SkyWalking Java Agent 与 Spring Boot 版本基本无关,但与字节码增强的框架版本有关;如遇不支持的框架版本,查看官方插件支持列表 |