微服务链路追踪组件Skywalking实战详解
摘要:Apache SkyWalking是一款开源的分布式系统性能监控工具,支持微服务架构的链路追踪和性能分析。它采用探针(Agent)采集数据,通过OAP平台分析处理,支持多种存储方式(ES/MySQL等),提供可视化UI展示调用链和性能指标。SkyWalking具有低侵入性、多语言支持、告警功能等特点,相比Zipkin等工具性能影响更小。本文详细介绍了SkyWalking的架构设计、安装部署、
一、SkyWalking简介
1.1 什么是SkyWalking
SkyWalking是一款国产开源的应用性能监控(APM)系统,专为微服务、云原生和容器化架构设计。它于2015年由吴晟开源,2017年加入Apache孵化器,现已成为Apache顶级项目。SkyWalking提供分布式追踪、服务网格遥测分析、度量聚合和可视化一体化解决方案。
核心价值:
-
串联调用链路,快速定位问题
-
理清微服务间依赖关系
-
分析微服务接口性能
-
追踪业务流程处理顺序
官方资源:
1.2 链路追踪组件选型对比
| 特性 | Zipkin | Pinpoint | SkyWalking | CAT |
|---|---|---|---|---|
| 实现方式 | 拦截请求,发送数据 | Java探针,字节码增强 | Java探针,字节码增强 | 代码埋点 |
| 接入方式 | 引入配置 | javaagent字节码 | javaagent字节码 | 代码侵入 |
| 协议 | HTTP/MQ | Thrift | gRPC | HTTP/TCP |
| 颗粒度 | 接口级 | 方法级 | 方法级 | 代码级 |
| 全局调用统计 | × | √ | √ | √ |
| JVM监控 | × | × | √ | √ |
| OpenTracing | √ | × | √ | × |
性能对比(探针对吞吐量影响):
-
SkyWalking:影响最小
-
Zipkin:影响适中
-
Pinpoint:影响明显(500并发时吞吐量从1385降至774)
1.3 SkyWalking主要功能特性
-
多语言支持:Java、.NET Core、Node.JS等自动探针
-
轻量高效:无需大数据平台和大量服务器资源
-
模块化设计:UI、存储、集群管理有多种机制可选
-
完整监控方案:分布式追踪、度量聚合、可视化
-
告警功能:支持自定义告警规则和多种通知方式
-
服务网格支持:通过Service Mesh网络代理收集数据
二、SkyWalking整体架构
2.1 架构组成
text
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Agent │────▶│ OAP │────▶│ Storage │
│ (探针) │ │(分析平台) │ │ (存储) │
└─────────────┘ └─────────────┘ └─────────────┘
│
┌──────┴──────┐
│ UI │
│ (界面) │
└─────────────┘
四大核心组件:
2.1.1 Agent(探针)
-
部署方式:与应用一起部署,通过-javaagent参数加载
-
功能:收集应用性能数据,发送给OAP服务器
-
技术:基于ByteBuddy字节码增强技术
2.1.2 OAP(Observability Analysis Platform)
-
功能:接收Agent数据,进行分析、聚合、存储
-
端口:
-
11800:接收Agent数据(gRPC)
-
12800:提供查询接口(HTTP)
-
2.1.3 Storage(存储)
-
支持存储:ElasticSearch、MySQL、TiDB、H2等
-
推荐:生产环境建议使用ElasticSearch
2.1.4 UI(用户界面)
-
默认UI:RocketBot UI(SkyWalking 7.0.0+)
-
端口:默认8080
-
功能:展示追踪数据、拓扑图、性能指标等
2.2 核心概念
-
服务(Service):提供相同功能的一组工作负载
-
服务实例(Service Instance):服务中的单个运行实例
-
端点(Endpoint):服务接收请求的路径(如HTTP URI)
-
追踪(Trace):一次请求的完整调用链
-
跨度(Span):Trace中的一个操作单元
三、SkyWalking环境搭建部署
3.1 下载与安装
下载地址:
bash
# SkyWalking APM wget https://archive.apache.org/dist/skywalking/9.1.0/apache-skywalking-apm-9.1.0.tar.gz # Java Agent(单独下载) wget https://archive.apache.org/dist/skywalking/java-agent/8.11.0/apache-skywalking-java-agent-8.11.0.tgz
目录结构:
text
apache-skywalking-apm-bin/
├── bin/ # 启动脚本
│ ├── startup.sh # 组合启动脚本
│ ├── oapService # OAP启动脚本
│ └── webappService # UI启动脚本
├── config/ # 配置文件
│ ├── application.yml # OAP配置
│ └── alarm-settings.yml # 告警配置
├── webapp/ # UI前端
├── oap-libs/ # OAP依赖库
└── agent/ # Agent探针
├── skywalking-agent.jar
├── config/
├── plugins/ # 必须插件
└── optional-plugins/ # 可选插件
3.2 快速启动(使用H2存储)
1)修改配置
yaml
# config/application.yml
storage:
selector: ${SW_STORAGE:h2}
2)启动服务
bash
# 启动OAP和UI bin/startup.sh # 查看日志 tail -f logs/skywalking-oap-server.log tail -f logs/webapp.log
3)访问UI
text
http://localhost:8080
3.3 端口说明
| 服务 | 端口 | 说明 |
|---|---|---|
| OAP Server | 11800 | 接收Agent数据(gRPC) |
| OAP Server | 12800 | 提供查询接口(HTTP) |
| Web UI | 8080 | 用户界面(可修改) |
四、SkyWalking快速开始
4.1 SkyWalking Agent追踪微服务
4.1.1 通过JAR包方式接入
Shell脚本启动方式:
bash
#!/bin/sh # SkyWalking Agent配置 export SW_AGENT_NAME=springboot-skywalking-demo export SW_AGENT_COLLECTOR_BACKEND_SERVICES=127.0.0.1:11800 export SW_AGENT_SPAN_LIMIT=2000 export JAVA_AGENT="-javaagent:/path/to/skywalking-agent.jar" java $JAVA_AGENT -jar your-application.jar
命令行参数方式:
bash
java -javaagent:/path/to/skywalking-agent.jar \
-DSW_AGENT_NAME=springboot-skywalking-demo \
-DSW_AGENT_COLLECTOR_BACKEND_SERVICES=127.0.0.1:11800 \
-jar your-application.jar
4.1.2 在IDEA中使用SkyWalking
配置JVM参数:
text
-javaagent:D:\skywalking\agent\skywalking-agent.jar -DSW_AGENT_NAME=springboot-skywalking-demo -DSW_AGENT_COLLECTOR_BACKEND_SERVICES=192.168.65.206:11800
4.1.3 跨多个微服务追踪
注意事项:
-
每个微服务都需要配置Agent
-
Gateway服务需要特殊插件支持
Gateway插件配置:
bash
# 拷贝Gateway插件到plugins目录 cp agent/optional-plugins/apm-spring-cloud-gateway-*.jar agent/plugins/ cp agent/optional-plugins/apm-spring-webflux-*.jar agent/plugins/
4.2 SkyWalking集成日志框架
4.2.1 集成Logback
添加依赖:
xml
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-logback-1.x</artifactId>
<version>8.11.0</version>
</dependency>
配置logback-spring.xml:
xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<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} [%tid] [%thread] %-5level %logger{36} - %msg%n</Pattern>
</layout>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="console"/>
</root>
</configuration>
日志输出示例:
text
2022-08-05 17:28:41.809 [TID:2fa2a77d1b244697aafb8a158ba5ad81.244.16596917217780005] [http-nio-8046] INFO ...
4.2.2 通过gRPC上报日志(v8.4.0+)
配置gRPC Appender:
xml
<appender name="grpc-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} [%tid] [%thread] %-5level %logger{36} - %msg%n</Pattern>
</layout>
</encoder>
</appender>
4.3 SkyWalking告警通知
4.3.1 告警规则配置
配置文件:config/alarm-settings.yml
示例规则:
yaml
rules:
service_resp_time_rule:
metrics-name: service_resp_time
op: ">"
threshold: 1000
period: 10
count: 3
silence-period: 5
message: 服务响应时间超过1000ms
规则参数说明:
-
metrics-name:度量名称(服务、实例、端点等) -
op:操作符(>、<、=) -
threshold:阈值 -
period:检查周期(分钟) -
count:触发次数 -
silence-period:静默期 -
message:告警消息
4.3.2 WebHook回调
配置回调接口:
yaml
webhooks: - http://localhost:8080/webhook
回调数据格式:
json
[
{
"scopeId": 1,
"scope": "SERVICE",
"name": "serviceA",
"id0": "c2VydmljZUE=",
"id1": "",
"ruleName": "service_resp_time_rule",
"alarmMessage": "服务响应时间超过1000ms",
"startTime": 1613913565462
}
]
实现回调接口:
java
@RestController
@RequestMapping("/webhook")
public class AlarmController {
@PostMapping
public void alarm(@RequestBody List<AlarmMessage> alarmMessages) {
for (AlarmMessage alarmMessage : alarmMessages) {
System.out.println(alarmMessage);
}
}
}
4.3.3 钉钉集成
配置示例:
yaml
dingtalkHooks:
textTemplate: |
{
"msgtype": "text",
"text": {
"content": "Apache SkyWalking Alarm: \n %s."
}
}
webhooks:
- url: https://oapi.dingtalk.com/robot/send?access_token=your_token
secret: your_secret
4.4 SkyWalking持久化追踪数据
4.4.1 基于MySQL持久化
1. 修改配置:
yaml
storage:
selector: ${SW_STORAGE:mysql}
mysql:
properties:
jdbcUrl: ${SW_JDBC_URL:"jdbc:mysql://localhost:3306/swtest"}
dataSource.user: ${SW_DATA_SOURCE_USER:root}
dataSource.password: ${SW_DATA_SOURCE_PASSWORD:root}
2. 添加MySQL驱动:
bash
# 将MySQL驱动包放到oap-libs目录 cp mysql-connector-java-8.0.xx.jar oap-libs/
3. 创建数据库:
sql
CREATE DATABASE swtest CHARACTER SET utf8 COLLATE utf8_general_ci;
4.4.2 基于ElasticSearch持久化
1. 修改配置:
yaml
storage:
selector: ${SW_STORAGE:elasticsearch}
elasticsearch:
namespace: ${SW_NAMESPACE:""}
clusterNodes: ${SW_STORAGE_ES_CLUSTER_NODES:localhost:9200}
user: ${SW_ES_USER:""}
password: ${SW_ES_PASSWORD:""}
2. 启动ElasticSearch:
bash
# 单节点启动 bin/elasticsearch -d # 查看状态 curl http://localhost:9200
4.5 自定义SkyWalking链路追踪
4.5.1 添加依赖
xml
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-trace</artifactId>
<version>8.11.0</version>
</dependency>
4.5.2 获取TraceId
java
@RestController
public class UserController {
@RequestMapping("/list")
public List<User> list() {
// 存储上下文信息
TraceContext.putCorrelation("name", "fox");
// 获取上下文信息
Optional<String> name = TraceContext.getCorrelation("name");
System.out.println("name = " + name.get());
// 获取TraceId
String traceId = TraceContext.traceId();
System.out.println("traceId = " + traceId);
return userService.list();
}
}
4.5.3 使用@Trace注解
java
@Service
public class UserService {
@Trace // 将该方法加入追踪链路
@Tag(key = "list", value = "returnedObj")
public List<User> list() {
return userMapper.list();
}
@Trace
@Tags({
@Tag(key = "param", value = "arg[0]"),
@Tag(key = "user", value = "returnedObj")
})
public User getById(Integer id) {
return userMapper.getById(id);
}
}
@Tag注解说明:
-
key:标签名称 -
value:标签值-
arg[0]:方法第一个参数 -
arg[1]:方法第二个参数 -
returnedObj:返回值
-
4.6 SkyWalking集群部署
4.6.1 集群架构
text
┌─────────────┐
│ Nginx │
│ (LB) │
└──────┬──────┘
┌──────┴──────┐
│ Web UI │
│ 集群 │
└──────┬──────┘
┌────────────┼────────────┐
│ │ │
┌───▼───┐ ┌───▼───┐ ┌───▼───┐
│ OAP1 │ │ OAP2 │ │ OAP3 │
└───┬───┘ └───┬───┘ └───┬───┘
│ │ │
┌───▼───────────▼───────────▼───┐
│ ElasticSearch │
│ 集群 │
└───────────────────────────────┘
4.6.2 配置步骤
1. 修改OAP配置(使用Nacos注册中心):
yaml
cluster:
selector: ${SW_CLUSTER:nacos}
nacos:
serviceName: ${SW_SERVICE_NAME:"SkyWalking_OAP_Cluster"}
hostPort: ${SW_CLUSTER_NACOS_HOST_PORT:localhost:8848}
namespace: ${SW_CLUSTER_NACOS_NAMESPACE:"public"}
2. 修改UI配置:
yaml
# webapp/webapp.yml
server:
port: 8080
spring:
cloud:
discovery:
simple:
instances:
oap-service:
- 192.168.1.101:12800
- 192.168.1.102:12800
- 192.168.1.103:12800
3. 启动顺序:
-
启动Nacos集群
-
启动ElasticSearch集群
-
启动多个OAP实例
-
启动UI服务
-
配置Nginx负载均衡
五、常见问题与解决方案
5.1 Gateway追踪不显示
问题:Spring Cloud Gateway服务在追踪链路中不显示
解决方案:
bash
# 拷贝Gateway相关插件 cp agent/optional-plugins/apm-spring-cloud-gateway-*.jar agent/plugins/ cp agent/optional-plugins/apm-spring-webflux-*.jar agent/plugins/
5.2 内存配置优化
调整JVM参数:
bash
# 修改bin/oapService.sh export JAVA_OPTS=" -Xms2g -Xmx2g -XX:+UseG1GC"
5.3 数据清理策略
配置数据保留时间:
yaml
# config/application.yml
recordDataTTL: ${SW_RECORD_DATA_TTL:90} # 记录数据保留90天
metricsDataTTL: ${SW_METRICS_DATA_TTL:90} # 指标数据保留90天
六、总结与最佳实践
6.1 部署建议
-
生产环境:使用ElasticSearch作为存储,配置集群模式
-
开发环境:可使用H2或MySQL,简化部署
-
监控范围:从核心业务服务开始,逐步扩大覆盖范围
6.2 性能优化
-
采样率调整:生产环境可适当降低采样率(如50%)
-
缓冲区配置:调整Agent缓冲区大小,平衡性能和数据完整性
-
网络优化:确保Agent与OAP之间的网络通畅
6.3 监控告警
-
关键指标:响应时间、错误率、吞吐量
-
告警分级:根据业务重要性设置不同级别的告警
-
通知渠道:结合邮件、钉钉、企业微信等多渠道通知
6.4 持续维护
-
版本升级:关注SkyWalking版本更新,及时升级
-
数据清理:定期清理过期数据,释放存储空间
-
性能监控:监控SkyWalking自身性能,确保监控系统稳定
七、学习资源推荐
本文基于SkyWalking v9.1.0版本编写,涵盖了从入门到生产部署的全流程。SkyWalking作为国产优秀的APM系统,在微服务监控领域表现出色,建议在实际项目中逐步应用,结合业务特点进行定制化配置。
更多推荐

所有评论(0)