SkyWalking 分布式链路追踪
一、为什么我们需要分布式链路追踪?
在单体架构时代,所有代码都在一个应用里,出了问题只需要看一个应用的日志,很容易定位。但到了微服务架构时代,情况完全变了。
微服务故障排查的四大痛点
-
日志分散,无法串联一个请求经过多个服务,日志分散在不同的服务器上,无法将同一个请求的所有日志串联起来。
-
性能瓶颈难以定位接口响应慢,但不知道是哪个服务、哪个方法慢,只能一个个服务去排查,效率极低。
-
故障根因难以确定一个错误可能是由上游服务的错误引起的,没有链路追踪,很难找到真正的根因。
-
依赖关系混乱微服务越来越多,服务之间的依赖关系越来越复杂,没有人能说清楚一个服务到底依赖了哪些其他服务。
分布式链路追踪的核心价值
分布式链路追踪系统就是为了解决这些痛点而生的,它能:
- 追踪完整请求链路:记录一个请求从进入系统到离开系统的完整路径
- 分析性能瓶颈:统计每个服务、每个方法的耗时,快速定位慢节点
- 可视化服务拓扑:自动生成服务之间的依赖关系图,一目了然
- 快速定位故障根因:通过链路 ID,一键查看整个请求的所有日志和异常信息
- 监控服务健康状态:实时监控服务的 QPS、响应时间、错误率等指标
- 自动告警:当服务出现异常时,自动发送告警通知
二、SkyWalking 是什么?
SkyWalking 是一款开源的应用性能监控(APM)和分布式链路追踪系统,由华为开源,目前是 Apache 基金会的顶级项目。它专门为微服务、云原生架构设计,支持 Java、Go、Python、Node.js 等多种语言。
SkyWalking 的核心优势
- 无侵入式:基于 Java Agent 技术,不需要修改任何业务代码,只需要在启动时添加一个参数
- 性能优秀:探针性能损耗极低,对应用的影响几乎可以忽略不计
- 功能丰富:支持链路追踪、性能分析、服务拓扑、日志集成、告警等多种功能
- 多语言支持:支持 Java、Go、Python、Node.js、C# 等主流编程语言
- 生态完善:无缝整合 Spring Cloud、Dubbo、gRPC、Kafka 等主流框架
- 可扩展性强:支持自定义插件、自定义指标、自定义告警
SkyWalking 整体架构
SkyWalking 采用 "探针 + 服务器 + UI" 的三层架构:
plaintext
┌─────────────────────────────────────────────────────────┐
│ 应用服务集群 │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 服务A(探针) │ │ 服务B(探针) │ │ 服务C(探针) │ │
│ └───────┬─────┘ └───────┬─────┘ └───────┬─────┘ │
└───────────────────────────┼─────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ OAP 服务器集群 │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 数据接收 │ │ 数据分析 │ │ 数据存储 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└───────────────────────────┬─────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ SkyWalking UI │
└─────────────────────────────────────────────────────────┘
- 探针(Agent):部署在应用服务中,负责采集应用的性能数据和链路数据,发送给 OAP 服务器
- OAP 服务器:负责接收探针发送的数据,进行分析和聚合,存储到数据库中
- UI 界面:提供可视化界面,展示服务拓扑、链路追踪、性能指标等数据
三、SkyWalking 核心概念
要真正用好 SkyWalking,必须先搞懂它的几个核心概念。
1. Trace(追踪)
一个 Trace 代表一个完整的请求链路,从用户发起请求到收到响应的整个过程。每个 Trace 都有一个唯一的 Trace ID,贯穿整个请求链路。
2. Span(跨度)
一个 Span 代表 Trace 中的一个操作,比如一个 HTTP 请求、一个数据库查询、一个 RPC 调用。每个 Span 都有一个唯一的 Span ID,并且包含父 Span ID,通过这种方式将所有 Span 串联成一个完整的 Trace。
3. Segment(段)
一个 Segment 代表一个服务中的一段链路,是同一个服务中所有 Span 的集合。当请求从一个服务进入另一个服务时,会生成一个新的 Segment。
4. Service(服务)
一个 Service 代表一个应用程序,对应微服务架构中的一个服务。每个 Service 都有一个唯一的名称。
5. Service Instance(服务实例)
一个 Service Instance 代表服务的一个运行实例,对应一个 JVM 进程。每个实例都有一个唯一的 ID。
6. Endpoint(端点)
一个 Endpoint 代表服务中的一个接口,比如一个 HTTP 接口、一个 RPC 方法。
四、Spring Boot 整合 SkyWalking 快速开始
整合 SkyWalking 非常简单,不需要修改任何业务代码,只需要在启动时添加一个 Java Agent 参数即可。
第一步:下载 SkyWalking
- 下载 SkyWalking 安装包:https://skywalking.apache.org/downloads/
- 解压到本地目录,比如
/usr/local/skywalking
解压后的目录结构:
plaintext
skywalking/
├── agent/ # 探针目录
│ ├── skywalking-agent.jar
│ └── config/
├── bin/ # 启动脚本
├── config/ # OAP配置文件
├── oap-libs/ # OAP依赖包
└── webapp/ # UI界面
第二步:启动 OAP 服务器和 UI
bash
运行
# 启动OAP服务器
cd /usr/local/skywalking/bin
./startup.sh
这个脚本会同时启动 OAP 服务器和 UI 界面。OAP 默认端口是 11800(gRPC)和 12800(HTTP),UI 默认端口是 8080。
启动完成后,访问http://localhost:8080,就可以看到 SkyWalking 的 UI 界面了。
第三步:启动应用服务,挂载探针
在启动你的 Spring Boot 应用时,添加以下 JVM 参数:
bash
运行
java -javaagent:/usr/local/skywalking/agent/skywalking-agent.jar \
-Dskywalking.agent.service_name=user-service \
-Dskywalking.collector.backend_service=127.0.0.1:11800 \
-jar user-service.jar
参数说明:
-javaagent:指定 SkyWalking 探针的路径skywalking.agent.service_name:服务名称,在 SkyWalking 中显示的名称skywalking.collector.backend_service:OAP 服务器的地址
第四步:查看链路数据
启动应用服务后,访问几个接口,然后刷新 SkyWalking UI 界面,就可以看到你的服务了。
点击 "拓扑图" 菜单,可以看到服务之间的依赖关系;点击 "追踪" 菜单,可以看到所有请求的链路信息。
五、核心功能详解
5.1 服务拓扑图
服务拓扑图是 SkyWalking 最直观的功能之一,它能自动生成服务之间的依赖关系图,让你一目了然地看到整个系统的架构。
在拓扑图中,每个节点代表一个服务,节点的大小代表服务的 QPS,节点的颜色代表服务的健康状态(绿色 = 正常,黄色 = 警告,红色 = 异常)。连线代表服务之间的调用关系,连线的粗细代表调用量。
通过拓扑图,你可以快速发现:
- 哪些服务是核心服务,调用量最大
- 哪些服务出现了异常
- 服务之间的依赖关系是否合理
- 是否存在循环依赖
5.2 分布式链路追踪
这是 SkyWalking 最核心的功能。点击 "追踪" 菜单,你可以看到所有请求的列表,每个请求都显示了 Trace ID、服务名称、端点、耗时、状态等信息。
点击任意一个请求,就可以看到这个请求的完整链路图。链路图以瀑布流的形式展示了每个 Span 的耗时、开始时间、结束时间,以及 Span 之间的父子关系。
通过链路图,你可以:
- 清晰地看到请求经过了哪些服务、哪些方法
- 快速定位哪个服务、哪个方法耗时最长
- 查看每个 Span 的详细信息,包括请求参数、响应结果、异常信息
- 通过 Trace ID,一键关联所有服务的日志
5.3 性能分析
SkyWalking 提供了强大的性能分析功能,可以从多个维度分析服务的性能:
- 服务维度:查看每个服务的 QPS、平均响应时间、P99 响应时间、错误率等指标
- 端点维度:查看每个接口的性能指标,找出慢接口
- 数据库维度:查看每个 SQL 语句的执行时间、执行次数,找出慢 SQL
- 实例维度:查看每个服务实例的性能指标,找出性能差的实例
5.4 日志集成
SkyWalking 可以和主流的日志框架(Logback、Log4j2)集成,将日志和链路追踪关联起来。
只需要在日志配置文件中添加[%traceId],就可以在日志中打印 Trace ID。这样,当你在 SkyWalking 中看到一个异常请求时,只需要复制 Trace ID,就可以在日志系统中搜索到这个请求的所有日志。
Logback 配置示例:
xml
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - [%traceId] %msg%n</pattern>
5.5 告警功能
SkyWalking 支持自定义告警规则,当服务的指标达到阈值时,自动发送告警通知。支持的告警方式包括:邮件、钉钉、企业微信、Webhook 等。
你可以配置以下告警规则:
- 服务响应时间超过阈值
- 服务错误率超过阈值
- 服务 QPS 超过阈值
- 数据库慢 SQL 数量超过阈值
六、高级特性:自定义链路追踪
默认情况下,SkyWalking 会自动拦截 Spring MVC、MyBatis、Dubbo 等主流框架的调用,生成链路数据。但对于一些自定义的方法,或者第三方框架的调用,你可能需要手动添加链路追踪。
6.1 使用 @Trace 注解
最简单的方式是使用@Trace注解,给需要追踪的方法加上这个注解,SkyWalking 就会自动为这个方法生成一个 Span。
java
运行
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
// 给这个方法添加链路追踪
@Trace(operationName = "查询用户信息")
public User getUserById(Long id) {
// 添加自定义标签
ActiveSpan.tag("user.id", id.toString());
User user = userMapper.selectById(id);
// 添加自定义日志
ActiveSpan.info("查询到用户:" + user.getName());
return user;
}
}
6.2 手动创建 Span
如果需要更灵活的控制,可以手动创建 Span:
java
运行
public void complexMethod() {
// 创建一个新的Span
Span span = ContextManager.createLocalSpan("复杂业务逻辑");
try {
// 业务逻辑
step1();
step2();
step3();
} catch (Exception e) {
// 记录异常
span.errorOccurred();
span.log(e);
throw e;
} finally {
// 停止Span
ContextManager.stopSpan();
}
}
七、生产环境集群部署
生产环境中,绝对不能使用单机 SkyWalking,否则 SkyWalking 挂了,整个监控系统就瘫痪了。SkyWalking 支持集群部署,官方推荐至少部署 3 个 OAP 节点。
7.1 生产环境架构
生产环境推荐使用以下架构:
- 3 个 OAP 节点:组成集群,保证高可用
- Elasticsearch 集群:存储 SkyWalking 的监控数据,推荐至少 3 个节点
- Nginx:作为 UI 的负载均衡,同时代理 OAP 的 HTTP 接口
7.2 部署步骤
- 部署 Elasticsearch 集群:SkyWalking 默认使用 H2 数据库,生产环境必须使用 Elasticsearch
- 修改 OAP 配置文件:修改
config/application.yml,配置 Elasticsearch 地址 - 启动多个 OAP 节点:在不同的服务器上启动 OAP,它们会自动组成集群
- 部署 UI:部署多个 UI 节点,前面用 Nginx 做负载均衡
- 配置探针:将探针的
backend_service配置为 Nginx 的地址
八、生产环境常见坑与最佳实践
坑 1:探针性能损耗
问题描述:担心 SkyWalking 探针会影响应用的性能。
解决方案:
- SkyWalking 探针的性能损耗非常低,一般在 5% 以内,对大多数应用来说可以忽略不计
- 合理设置采样率,不需要采集所有请求,生产环境一般设置为 10%-30%
- 避免给所有方法都加 @Trace 注解,只给核心业务方法加
坑 2:数据量太大,Elasticsearch 磁盘爆满
问题描述:SkyWalking 会产生大量的监控数据,时间长了会占满磁盘。
解决方案:
- 合理设置数据保留时间,默认是 7 天,生产环境可以根据需要设置为 15-30 天
- 定期清理 Elasticsearch 的历史索引
- 对 Elasticsearch 进行分片和副本优化
坑 3:链路不完整
问题描述:有些请求的链路不完整,缺少部分服务的 Span。
常见原因:
- 没有给对应的服务挂载探针
- 第三方框架没有对应的插件
- 跨线程调用没有传递 Trace ID
解决方案:
- 确保所有服务都挂载了探针
- 下载对应的第三方插件,放到
agent/plugins目录下 - 对于跨线程调用,使用 SkyWalking 提供的
CallableWrapper或RunnableWrapper
最佳实践
- 统一服务命名规范:所有服务使用统一的命名规范,比如
项目名-服务名 - 合理设置采样率:生产环境设置为 10%-30%,既保证监控效果,又减少性能损耗和数据量
- 核心方法添加自定义链路:给核心业务方法添加 @Trace 注解和自定义标签,方便排查问题
- 集成日志系统:将 Trace ID 打印到日志中,实现日志和链路的关联
- 配置合理的告警规则:不要配置太多告警,避免告警轰炸,只配置核心指标的告警
- 定期优化监控指标:定期清理无用的监控指标,减少数据量
- 监控 SkyWalking 本身:监控 SkyWalking OAP 和 Elasticsearch 的运行状态,避免监控系统本身出问题
- 升级到最新稳定版:SkyWalking 更新很快,新版本会修复很多 bug,提升性能
总结
分布式链路追踪是微服务架构中不可或缺的组件,它能让你清晰地看到系统的运行状态,快速定位和解决线上故障。而 SkyWalking 是目前最优秀的开源 APM 工具之一,它无侵入、性能好、功能丰富,是中小团队的最佳选择。
- 微服务故障排查的四大痛点,催生了分布式链路追踪技术
- SkyWalking 采用 "探针 + OAP+UI" 的三层架构,无侵入式部署
- 核心概念包括 Trace、Span、Segment、Service、Instance、Endpoint
- Spring Boot 整合 SkyWalking 非常简单,只需要添加一个 JVM 参数
- 核心功能包括服务拓扑图、分布式链路追踪、性能分析、日志集成和告警
- 生产环境必须部署集群,使用 Elasticsearch 存储数据
- 遵循最佳实践,避开常见的坑,让你的监控系统更加稳定可靠
更多推荐




所有评论(0)