【SkyWalking从入门到精通】第75篇:SkyWalking生产实践避坑指南——填坑记之Agent不上报、Trace丢失、告警不触发
·
下一篇【第74篇】SkyWalking 9.x新特性——K8s原生集成、Continuous Profiling与Layer概念
上一篇【第76篇】SkyWalking完整技术栈选型决策树——从Agent到OAP到存储的企业级选型指南
一、开篇 —— 每个SkyWalking用户的必修课
在SkyWalking社区,有一个流传很久的笑话:
“安装SkyWalking只需要5分钟,排查SkyWalking为什么没数据需要5小时。”
这不是玩笑。SkyWalking作为一个分布式系统,涉及Agent、网络、OAP、存储四个环节,任何一个环节出问题,都会导致"看起来一切正常,但就是没数据"。
本文是我在生产环境中"填坑"多年的经验总结,用最直白的话讲最实战的排查思路。每一个坑背后都有一个深夜排查的血泪故事。
二、第一大坑:Agent不上报数据
这是最高频的问题,没有之一。
2.1 从外到内的六步排查法
+------------------------------------------------------------------+
| Agent不上报数据的六步排查法 |
+------------------------------------------------------------------+
| |
| Step 1: Agent启动了吗? |
| ┌────────────────────────────────────────────────────┐ │
| │ 检查: 启动日志中有没有SkyWalking的日志 │ │
| │ 命令: grep "SkyWalking" app.log │ │
| │ 正常: "SkyWalking Agent 9.7.0 initialized" │ │
| │ 异常: 没有 → 检查 -javaagent: 参数是否正确配置 │ │
| └────────────────────────────────────────────────────┘ │
| │ │
| 没有日志? ↓ │
| │ │
| Step 2: Agent加载了你的插件吗? |
| ┌────────────────────────────────────────────────────┐ │
| │ 检查: plugins/ 目录下的Jar是否正确 │ │
| │ 注意: 有些Jar需要放 optional-plugins/ │ │
| │ 有些Jar需要放 bootstrap-plugins/ │ │
| │ 命令: ls skywalking-agent/plugins/ │ │
| └────────────────────────────────────────────────────┘ │
| │ │
| 插件没问题? ↓ │
| │ │
| Step 3: 网络通吗? |
| ┌────────────────────────────────────────────────────┐ │
| │ 检查: Agent能否连接到OAP │ │
| │ 命令: telnet oap-server 11800 │ │
| │ 正常: Connected to oap-server │ │
| │ 异常: Connection refused / timeout │ │
| │ → 检查防火墙/安全组/网络策略 │ │
| └────────────────────────────────────────────────────┘ │
| │ │
| 网络通的? ↓ │
| │ │
| Step 4: 注册成功了吗? |
| ┌────────────────────────────────────────────────────┐ │
| │ 检查: OAP日志中是否有注册记录 │ │
| │ 命令: grep "register" oap.log │ │
| │ 正常: "register service [order-service] success" │ │
| │ 异常: 没有注册日志 → 检查service_name配置 │ │
| │ agent.service_name=${SW_AGENT_NAME:YourName} │ │
| └────────────────────────────────────────────────────┘ │
| │ │
| 注册成功? ↓ │
| │ │
| Step 5: 数据真的发了吗? |
| ┌────────────────────────────────────────────────────┐ │
| │ 检查: Agent的GRPCChannel状态 │ │
| │ 日志: "Report trace segment to collector" │ │
| │ 如果没有 → Trace没有被创建 → 检查插件是否拦截 │ │
| └────────────────────────────────────────────────────┘ │
| │ │
| 数据发了? ↓ │
| │ │
| Step 6: OAP处理了吗? |
| ┌────────────────────────────────────────────────────┐ │
| │ 检查: OAP日志中是否有数据处理记录 │ │
| │ 检查: ES中是否有新数据 │ │
| │ curl "localhost:9200/segment*/_count" │ │
| │ → 如果ES有数据但UI看不到 → 可能是时间范围问题 │ │
| └────────────────────────────────────────────────────┘ │
| |
+------------------------------------------------------------------+
2.2 一个经典案例
案例:Agent启动正常、网络通、注册成功,但UI上就是没数据。
排查过程:
# 1. Agent日志里搜索"report"
grep "report" agent.log
# 结果: (空) → Trace根本没产生!
# 2. 检查应用代码
# 发现:应用是一个纯定时任务,没有任何HTTP请求或RPC调用
# 定时任务里直接操作数据库 → 没有创建EntrySpan!
# 3. 解决方案
# 为定时任务添加手动追踪
@Scheduled(fixedDelay = 60000)
public void myTask() {
AbstractSpan span = ContextManager.createEntrySpan(
"/scheduled/myTask", null
);
try {
// 定时任务逻辑
} finally {
ContextManager.stopSpan();
}
}
教训:纯批处理/定时任务应用需要手动创建EntrySpan,因为SkyWalking不会自动拦截main方法或@ Scheduled方法。
三、第二大坑:Trace数据不完整
3.1 截断的Trace是运营的噩梦
+------------------------------------------------------------------+
+ Trace不完整的几种典型症状 +
+------------------------------------------------------------------+
| |
| 症状1: "只有入站,没有出站" |
| ┌────────────────────────────────────────────────────┐ │
| │ Agent A (order-service) Agent B (user-svc) │ │
| │ ┌─────────┐ ┌─────────┐ │ │
| │ │EntrySpan│ ── OKHttp调用 ──→ │ ??? │ │ │
| │ │ │ │ 没数据! │ │ │
| │ └─────────┘ └─────────┘ │ │
| │ │ │
| │ 原因: Agent B的插件没拦截到请求 │ │
| │ → 检查user-svc的skywalking-agent配置 │ │
| │ → OKHttp插件是否启用: plugin.okhttp.trace = true │ │
| └────────────────────────────────────────────────────┘ │
| |
| 症状2: "方法调用丢失" |
| ┌────────────────────────────────────────────────────┐ │
| │ Trace中看到: │ │
| │ EntrySpan → ExitSpan(DB) │ │
| │ 但中间应该还有一个LocalSpan(缓存查询)不见了! │ │
| │ │ │
| │ 原因: 缓存客户端(Redis/Caffeine)插件未加载 │ │
| │ → 检查对应插件Jar是否在plugins/目录下 │ │
| └────────────────────────────────────────────────────┘ │
| |
| 症状3: "Span有但没有父子关系" |
| ┌────────────────────────────────────────────────────┐ │
| │ 两个Span显示为独立的Trace,而非父子关系 │ │
| │ │ │
| │ 原因: sw8 header丢失 │ │
| │ → 检查HTTP Client是否过滤了Header │ │
| │ → 检查Nginx/网关是否透传自定义Header │ │
| │ → 检查Dubbo Filter是否有自定义逻辑 │ │
| └────────────────────────────────────────────────────┘ │
| |
+------------------------------------------------------------------+
3.2 Trace不完整排查清单
# Trace完整性排查
# 1. 检查sw8 header是否被传播
# 在服务端打印所有Header
@GetMapping("/test")
public String test(HttpServletRequest request) {
Enumeration<String> headers = request.getHeaderNames();
while (headers.hasMoreElements()) {
String name = headers.nextElement();
System.out.println(name + ": " + request.getHeader(name));
}
return "ok";
}
# 如果sw8 header缺失:
# - 检查网关/LoadBalancer是否过滤了自定义Header
# - Nginx: proxy_pass_request_headers on;
# - Spring Cloud Gateway: 检查Filter顺序
# 2. 检查异步调用
# @Async方法中的Trace是否连续
# → 确保使用了ContextSnapshot
四、第三大坑:告警不触发
4.1 告警规则的调试
# 告警调试配置
rules:
# 调试用的小阈值规则
test_alert:
metrics-name: service_cpm
threshold: 1 # 只要有一次调用就告警
op: ">"
period: 1 # 只检查1分钟
count: 1 # 出现1次就告警
message: "TEST: service {name} has traffic"
# 如果这个告警都不触发,说明:
# 1. OAP没收到Metrics数据
# 2. 告警规则格式有问题
# 3. 告警配置没有被OAP加载
4.2 告警不触发的常见原因
原因1: 告警规则文件位置不对
- 检查: oap-server/config/alarm-settings.yml 是否存在
- 如果通过ConfigMap挂载,确认挂载路径正确
原因2: 指标名拼写错误
- service_resp_time ✓
- service_response_time ✗
原因3: OAP没有重启加载新规则
- 需要重启OAP或使用动态配置
原因4: 告警通知渠道配置错误
- 检查webhook URL是否可达
- 检查钉钉/企业微信的token是否正确
原因5: 静默期未过
- silence-period: 10 → 告警后10分钟内不再发送
- 调整silence-period或等静默期过去
五、第四大坑:Elasticsearch存储问题
5.1 ES集群变红
# 症状:SkyWalking UI打开很慢或报错
# 排查:
# 1. 检查ES集群健康
curl http://es-node:9200/_cluster/health
# {"status":"red",...} ← 危险!
# 2. 检查磁盘
curl http://es-node:9200/_cat/allocation?v
# 如果磁盘使用率 > 85% → ES会拒绝写入
# 3. 紧急处理
# 删除旧索引释放空间
curl -X DELETE "http://es-node:9200/sw_segment-20260701"
# 或调高磁盘水位线(临时方案)
curl -X PUT "http://es-node:9200/_cluster/settings" -H 'Content-Type: application/json' -d'
{
"transient": {
"cluster.routing.allocation.disk.watermark.low": "90%",
"cluster.routing.allocation.disk.watermark.high": "95%"
}
}'
5.2 索引爆炸
# 问题: 每天产生几百个索引,ES性能急剧下降
# 原因分析:
# SkyWalking为每种指标类型创建按天分片的索引
# 如果指标类型很多(自定义了很多OAL指标),索引数量会爆炸
# 解决方案:
# 1. 限制索引保留天数
storage:
elasticsearch:
traceDataTTL: 7 # Trace保留7天
metricDataTTL: 7 # 指标保留7天
recordDataTTL: 7 # 记录保留7天
# 2. 定时清理旧索引
# 创建ES ILM策略(Index Lifecycle Management)
# 或者使用CronJob定时删除
0 2 * * * curl -X DELETE "http://es:9200/sw_*-$(date -d '8 days ago' +%Y%m%d)"
六、第五大坑:UI展示异常
# 症状1: 拓扑图显示白屏
# 排查:
# 1. 浏览器F12 → Console → 看JS报错
# 2. 检查OAP的GraphQL接口是否正常
curl http://oap-server:12800/graphql
# 3. 清除浏览器缓存
# 4. 升级UI版本(可能和OAP版本不匹配)
# 症状2: Trace详情页加载超时
# 排查:
# 1. 检查ES查询速度
# 2. 检查网络(UI→OAP→ES)
# 3. Trace数据量太大(超过ES默认限制)
# 设置 OAP 参数
# SW_CORE_GRPC_MAX_MESSAGE_SIZE=104857600
# 症状3: Dashboard加载不出来
# 排查:
# 检查GraphQL查询是否正确
# 有可能是OAP版本和UI版本不一致
# 查看UI容器的日志: kubectl logs deployment/skywalking-ui
七、第六大坑:升级SkyWalking版本
7.1 升级惨案与正确姿势
+------------------------------------------------------------------+
| 升级SkyWalking的正确姿势 |
+------------------------------------------------------------------+
| |
| ❌ 错误做法: |
| ┌────────────────────────────────────────────────────┐ │
| │ 1. 周五下午直接升 │ │
| │ 2. 不备份就升 │ │
| │ 3. 跨多个大版本升 │ │
| │ 4. 全量切换,不留灰度 │ │
| └────────────────────────────────────────────────────┘ │
| |
| ✓ 正确做法: |
| ┌────────────────────────────────────────────────────┐ │
| │ 1. 周二/周三升级(留足修复时间) │ │
| │ 2. 先搭验证环境,用生产数据量压测 │ │
| │ 3. 确认Agent和OAP版本兼容 │ │
| │ 4. 逐步灰度:先升20% Agent → 观察 → 全部升Agent │ │
| │ 5. 升OAP:先启一个新版本OAP集群 → 切换流量 → 停旧 │ │
| │ 6. 保留旧版本环境一周(快速回退能力) │ │
| └────────────────────────────────────────────────────┘ │
| |
+------------------------------------------------------------------+
# 升级检查清单
# ==============
# 1.0 升级前
echo "=== 升级前检查 ==="
echo "1. 确认当前版本:"
grep "version" skywalking-agent/config/agent.config
echo "2. 确认目标版本Release Notes"
echo "3. 备份OAP配置和ES数据"
echo "4. 确认新版本Agent兼容旧版本OAP(滚动升级的关键)"
# 2.0 升级步骤
echo "=== Agent灰度升级 ==="
# 先升级1个Pod的Agent,观察15分钟
kubectl set image deployment/order-service \
app=order-service:v2-with-new-agent
# 检查:
# - UI上是否有新数据
# - 告警是否正常
# - Agent日志有没有异常
# 3.0 OAP升级
echo "=== OAP升级 ==="
# 使用新namespace部署新版本OAP
helm install skywalking-v2 skywalking/skywalking \
--namespace monitoring-v2 \
--values new-values.yaml \
--set oap.image.tag=9.3.0
# 将Agent流量逐步切到新OAP
# 观察数据完整性
# 确认无误后,停止旧OAP
八、总结:防坑口诀
+------------------------------------------------------------------+
| SkyWalking生产防坑口诀 |
+------------------------------------------------------------------+
| |
| Agent不上报 → 六步排查 (启动→插件→网络→注册→发送→处理) |
| Trace断了 → 找sw8 header (网关/代理/Filter 没透传?) |
| 告警不触发 → 调试规则 (先验证最简单的告警能否触发) |
| ES红了 → 马上看磁盘 + 删旧索引 |
| UI白屏 → F12看Console + 清缓存 |
| 要升级 → 选周二 + 先灰度Agent + 再升OAP |
| |
+------------------------------------------------------------------+
下一篇【第74篇】SkyWalking 9.x新特性——K8s原生集成、Continuous Profiling与Layer概念
上一篇【第76篇】SkyWalking完整技术栈选型决策树——从Agent到OAP到存储的企业级选型指南
更多推荐


所有评论(0)