1. 为什么需要链路追踪?
在微服务架构中,一个外部请求往往需要经过多个内部服务调用才能完成。当系统出现性能问题时,传统的日志监控方式很难快速定位问题所在。想象一下,你正在运营一个电商平台,用户投诉"下单慢",但这个请求可能经过了网关、用户服务、商品服务、订单服务、支付服务等多个环节,传统方式需要逐个服务查日志,效率极低。
Skywalking作为一款开源的APM(应用性能监控)系统,通过分布式追踪技术,可以完整记录请求在系统中的流转路径,并自动生成调用链路图。它能告诉你:
- 请求经过了哪些服务
- 每个服务的处理耗时
- 是否存在异常或错误
- 系统资源消耗情况
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境准备与Skywalking部署
2.1 Skywalking服务端部署
Skywalking采用服务端+客户端的架构模式。我们先部署服务端:
bash复制# 下载最新版Skywalking(以9.4.0为例)
wget https://archive.apache.org/dist/skywalking/9.4.0/apache-skywalking-apm-9.4.0.tar.gz
tar -zxvf apache-skywalking-apm-9.4.0.tar.gz
cd apache-skywalking-apm-bin
# 修改存储配置(以Elasticsearch为例)
vim config/application.yml
storage:
selector: ${SW_STORAGE:elasticsearch}
elasticsearch:
nameSpace: ${SW_NAMESPACE:""}
clusterNodes: ${SW_STORAGE_ES_CLUSTER_NODES:localhost:9200}
# 启动服务端
bin/startup.sh
服务端启动后,默认UI访问地址为http://localhost:8080
提示:生产环境建议使用Elasticsearch作为存储后端,单机测试可以使用H2内存数据库。
2.2 SpringBoot项目准备
创建一个基础的SpringBoot项目,确保有以下依赖:
xml复制<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 用于模拟跨服务调用 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
3. SpringBoot集成Skywalking客户端
3.1 添加Skywalking Java Agent
Skywalking通过Java Agent方式实现无侵入式监控,不需要修改业务代码。
- 下载Java Agent:
bash复制wget https://archive.apache.org/dist/skywalking/java-agent/8.16.0/apache-skywalking-java-agent-8.16.0.tgz
tar -zxvf apache-skywalking-java-agent-8.16.0.tgz
- 启动SpringBoot应用时添加JVM参数:
bash复制java -javaagent:/path/to/skywalking-agent/skywalking-agent.jar \
-Dskywalking.agent.service_name=your-service-name \
-Dskywalking.collector.backend_service=localhost:11800 \
-jar your-application.jar
关键参数说明:
agent.service_name:服务名称,会在Skywalking UI中显示collector.backend_service:Skywalking服务端地址
3.2 通过Maven插件集成(可选)
如果不希望每次启动都手动添加JVM参数,可以使用Maven插件:
xml复制<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<jvmArguments>
-javaagent:${skywalking.agent.path}
-Dskywalking.agent.service_name=${skywalking.agent.service_name}
-Dskywalking.collector.backend_service=${skywalking.collector.backend_service}
</jvmArguments>
</configuration>
</plugin>
</plugins>
</build>
然后在application.properties中配置:
properties复制skywalking.agent.path=/path/to/skywalking-agent/skywalking-agent.jar
skywalking.agent.service_name=order-service
skywalking.collector.backend_service=localhost:11800
4. 高级配置与功能扩展
4.1 自定义追踪点
虽然Skywalking能自动追踪HTTP请求和数据库调用,但有时我们需要手动添加追踪点:
java复制import org.apache.skywalking.apm.toolkit.trace.Trace;
import org.apache.skywalking.apm.toolkit.trace.TraceContext;
@RestController
public class OrderController {
@Trace // 标记该方法需要被追踪
@GetMapping("/create")
public String createOrder() {
// 获取当前TraceID
String traceId = TraceContext.traceId();
// 业务逻辑...
return "Order created, traceId: " + traceId;
}
}
4.2 跨进程追踪
在微服务场景下,请求会跨越多个服务。确保在服务间传递追踪上下文:
- 使用Feign客户端时,添加
skywalking-feign-default-http-9.x插件:
xml复制<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-trace</artifactId>
<version>8.16.0</version>
</dependency>
- 在Feign接口上添加
@Trace注解:
java复制@FeignClient(name = "inventory-service")
public interface InventoryClient {
@Trace
@PostMapping("/reduce")
String reduceStock(@RequestBody OrderDTO order);
}
4.3 告警配置
Skywalking支持灵活的告警规则配置。修改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: 服务 {name} 响应时间超过1秒
service_error_rate_rule:
metrics-name: service_error_rate
op: ">"
threshold: 0.1
period: 10
count: 2
message: 服务 {name} 错误率超过10%
5. 常见问题排查
5.1 数据未上报
现象:Skywalking UI中看不到服务数据
排查步骤:
- 检查agent日志
logs/skywalking-api.log是否有错误 - 确认collector地址是否正确
- 检查网络连通性:
bash复制
telnet localhost 11800 - 确认服务名称是否冲突
5.2 追踪链路不完整
现象:跨服务调用链路中断
解决方案:
- 确保所有服务都安装了Skywalking agent
- 检查HTTP头中是否包含
sw8相关字段 - 对于异步调用,手动传递上下文:
java复制ContextCarrier contextCarrier = new ContextCarrier(); ContextManager.inject(contextCarrier); // 在异步任务中恢复上下文 ContextManager.extract(contextCarrier);
5.3 性能影响
Skywalking agent会带来一定的性能开销,通常小于3%。如果发现性能下降明显:
- 调整采样率:
properties复制-Dskywalking.agent.sample_n_per_3_secs=10 # 每秒采样数 - 关闭不必要的插件:
properties复制-Dskywalking.agent.exclude_plugins=jdbc,lettuce - 增加JVM内存:
properties复制-Xmx512m -Xms512m
6. 生产环境最佳实践
-
命名规范:
- 服务名:
业务线-服务类型-环境,如trade-order-service-prod - 实例名:
hostname_ip,如node-1_192.168.1.100
- 服务名:
-
存储优化:
yaml复制storage: elasticsearch: bulkActions: 1000 # 批量写入条数 flushInterval: 15 # 刷新间隔(秒) concurrentRequests: 2 # 并发请求数 -
高可用部署:
- OAP服务集群部署
- 使用Nginx做UI负载均衡
- 存储使用Elasticsearch集群
-
安全配置:
properties复制-Dskywalking.agent.authentication=your-token -Dskywalking.trace.ignore_path=/healthcheck,/metrics
我在实际项目中发现,对于Spring Cloud Gateway这类网关服务,需要特别注意:
- 增加
-Dskywalking.plugin.springmvc.use_qualified_name_as_endpoint_name=true参数 - 对于高并发网关,适当降低采样率
- 启用
gateway-2.1.x插件以获取更完整的链路信息
