适合人群 :Java 微服务测试工程师、SDET、性能诊断工程师、可观测性平台使用者
阅读时长:约 40 分钟
前言
前几篇我们把 单机 JVM 诊断 讲透了:Linux 命令看资源、三剑客看快照、Arthas 做在线动态追踪。但微服务架构下,一个用户请求会横跨十几个服务 ------订单服务调库存、库存调商品、商品调缓存......这时候光看单机的 jstack,就像只检查一辆车却想诊断整条高速公路的堵点。
这就是 全链路诊断 要解决的问题。它由两个互补的能力组成:
- 🔭 SkyWalking(链路追踪 / APM) :从 宏观 看请求穿越哪些服务、每个服务耗时多少、哪里是慢调用、哪里在报错------定位到"哪个服务、哪个 Trace"
- 🔬 Arthas(单机在线诊断) :从 微观 看这个服务里 具体哪个方法、什么参数、为什么慢 ------定位到"哪行代码"
💡 一句话理解分工:
- SkyWalking 负责"带你看病到科室"(发现慢调用在哪个服务)
- Arthas 负责"做微创手术确诊病因"(钻进方法看入参/返回值/耗时)
两者结合 = 从"哪个服务慢"到"哪行代码慢"的端到端闭环,排查时间从小时级压缩到分钟级。
本文按 "为什么需要全链路 → SkyWalking 搭建 → 发现异常 Trace → Arthas 钻入确诊 → 真实案例 → 自动化联动" 的逻辑组织,所有操作在 Spring Boot 2.x/3.x + SkyWalking 8.x/9.x + JDK 8/11/17 下验证。
目录
- 一、为什么单机诊断不够用:微服务诊断的真实痛点
- [二、全链路诊断全景:SkyWalking + Arthas 协作模型](#二、全链路诊断全景:SkyWalking + Arthas 协作模型)
- [三、SkyWalking 快速搭建(Docker 一键版)](#三、SkyWalking 快速搭建(Docker 一键版))
- [四、Java 微服务接入 SkyWalking(探针方式)](#四、Java 微服务接入 SkyWalking(探针方式))
- [五、SkyWalking UI 实战:发现慢调用与异常链路](#五、SkyWalking UI 实战:发现慢调用与异常链路)
- [六、从 Trace 到 Arthas:故障定位的桥梁](#六、从 Trace 到 Arthas:故障定位的桥梁)
- 七、实战案例:从「下单超时」到「定位具体代码」
- 八、高级技巧:自定义标签、告警与日志关联
- [九、SkyWalking vs 竞品选型](#九、SkyWalking vs 竞品选型)
- 十、生产最佳实践与常见坑
- [十一、容器与 Kubernetes 部署](#十一、容器与 Kubernetes 部署)
- [附:命令 / 配置速查表](#附:命令 / 配置速查表)
一、为什么单机诊断不够用:微服务诊断的真实痛点
1.1 一个真实场景
假设你是测试工程师,接到反馈:"下单接口偶尔超时(>3s)"。
如果用之前的单机工具,你会怎么查?
订单服务 Pod → jstack → 看到很多线程在等库存服务响应
↓
库存服务 Pod → jstack → 看到线程在等商品服务
↓
商品服务 Pod → jstack → 看到线程在查数据库,慢 SQL
痛点:
- ❌ 要挨个登录 N 个 Pod 抓 jstack,效率低、易遗漏
- ❌ 抓到的栈是"某一瞬间"的,无法确认是不是导致这次超时的原因
- ❌ 无法还原"这一次请求"的完整路径和耗时分布
- ❌ 靠日志串联? 各服务日志散落在不同机器,靠 traceId 人工 grep 极其痛苦
1.2 全链路追踪解决什么
全链路追踪的核心是 Trace + Span 模型:
一个用户请求 = 1 个 Trace
├── Span1: 网关 (2ms)
├── Span2: 订单服务 (120ms)
│ ├── Span2.1: 调库存 (80ms) ← 慢
│ │ └── Span2.1.1: 查库存DB (75ms) ← 瓶颈
│ └── Span2.2: 调优惠券 (30ms)
└── Span3: 支付服务 (50ms)
- TraceID:贯穿整个请求的全局唯一 ID,所有服务共用
- Span:一个服务/一次调用的耗时单元,有父子关系
→ 一次查询就能看到整条链路的拓扑和耗时分布,直接告诉你是「库存服务的数据库查询」慢。
1.3 SkyWalking 在其中的角色
SkyWalking 是 Apache 顶级项目,国产开源 APM(应用性能监控),提供:
| 能力 | 说明 |
|---|---|
| 分布式追踪(Tracing) | Trace/Span 可视化,慢调用高亮 |
| 性能指标(Metrics) | QPS、响应时间、成功率(拓扑图实时) |
| 日志关联(Logging) | 通过 TraceID 串联各服务日志 |
| 告警(Alarm) | 基于指标规则自动告警 |
| 无侵入探针 | Java 通过 -javaagent 自动埋点,不改代码 |
💡 和 Arthas 的关系:SkyWalking 发现"哪个服务/链路异常",Arthas 钻进去看"为什么异常",两者接力。
二、全链路诊断全景:SkyWalking + Arthas 协作模型
2.1 整体架构
┌──────────────────────────────────────┐
│ 运维 / 测试工程师 │
└──────────────┬───────────────────────┘
│ ① 看 SkyWalking UI 发现慢 Trace
▼
┌──────────────────────────────────────────────────────────────┐
│ SkyWalking 后端 │
│ OAP Server (分析) + Storage (ES/H2/MySQL) + UI (Rocketbot)│
└──────────────┬───────────────────────────────────────────────┘
│ 收集 Trace/Metric
▲
│ gRPC (agent → OAP)
┌──────────────┴──────────────┐
│ Java 微服务 (Pod/容器) │
│ │
│ ┌────────────────────────┐ │
│ │ SkyWalking Agent │ │── 自动埋点,上报 Trace
│ │ (-javaagent探针) │ │
│ └────────────────────────┘ │
│ │ │
│ │ ② 发现异常后 │
│ ▼ │
│ ┌────────────────────────┐ │
│ │ Arthas (动态 attach) │ │── watch/trace/redefine
│ └────────────────────────┘ │
└──────────────────────────────┘
2.2 标准排查闭环(记住这个流程)
① SkyWalking UI 发现慢调用
│ (哪个服务 / 哪个 TraceID / 哪个 Span 慢)
▼
② 根据拓扑图 + Trace 详情定位嫌疑服务 & 实例
│
▼
③ 拿到 TraceID + 实例 IP/Pod,登录该实例
│
▼
④ Arthas attach 到该进程,用 watch/trace 钻入具体方法
│ (入参、返回值、耗时、调用链)
▼
⑤ 定位根因(慢 SQL / 死循环 / 锁竞争 / 外部依赖慢)
│
▼
⑥ 必要时 Arthas redefine 热修复,或走发版
│
▼
⑦ 回 SkyWalking 验证指标恢复 → 闭环
🎯 这就是「可观测性三支柱(Traces/Metrics/Logs)+ 在线诊断」的完整落地。
三、SkyWalking 快速搭建(Docker 一键版)
3.1 单机 Docker Compose 部署(测试环境推荐)
yaml
# docker-compose.yml
version: '3.8'
services:
oap:
image: apache/skywalking-oap-server:9.7.0
container_name: skywalking-oap
ports:
- "11800:11800" # gRPC (agent 上报)
- "12800:12800" # HTTP (UI 查询)
environment:
- SW_STORAGE=elasticsearch
- SW_STORAGE_ES_CLUSTER_NODES=es:9200
depends_on:
- es
ui:
image: apache/skywalking-ui:9.7.0
container_name: skywalking-ui
ports:
- "8080:8080"
environment:
- SW_OAP_ADDRESS=http://oap:12800
depends_on:
- oap
es:
image: docker.elastic.co/elasticsearch/elasticsearch:7.17.0
container_name: es
environment:
- discovery.type=single-node
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
ports:
- "9200:9200"
bash
# 启动
docker compose up -d
# 验证 OAP 健康
curl http://localhost:12800/health check
# 访问 UI
open http://localhost:8080
⚠️ 生产建议:存储用 Elasticsearch 集群 ,OAP 部署多副本;测试/本地用 H2 内存数据库 更轻量(把
SW_STORAGE改为h2并去掉 es 依赖)。
3.2 存储选型对比
| 存储 | 适用场景 | 说明 |
|---|---|---|
| H2 | 本地/测试 | 零依赖,重启数据丢 |
| Elasticsearch | 生产推荐 | 性能好,支持大规模 Trace |
| MySQL | 小规模 | 简单,量大性能差 |
| TiDB | 超大规模 | 可观测性平台级 |
四、Java 微服务接入 SkyWalking(探针方式)
4.1 方式一:-javaagent 启动参数(最常用)
bash
# 1. 下载 SkyWalking Agent
wget https://archive.apache.org/dist/skywalking/9.7.0/apache-skywalking-apm-9.7.0.tar.gz
tar -xzf apache-skywalking-apm-9.7.0.tar.gz
# agent 目录:apache-skywalking-apm-bin/agent/
# 2. 启动微服务时挂载 agent
java \
-javaagent:/opt/skywalking/agent/skywalking-agent.jar \
-Dskywalking.agent.service_name=order-service \
-Dskywalking.collector.backend_service=oap:11800 \
-jar order-service.jar
关键参数:
| 参数 | 含义 |
|---|---|
-javaagent:.../skywalking-agent.jar |
挂载探针(自动埋点) |
service_name |
服务名(UI 上显示) |
backend_service |
OAP 地址(IP:11800) |
✅ 无侵入 :不改一行业务代码,重启即生效。支持的框架:Spring Cloud、Dubbo、gRPC、Tomcat、JDBC、Redis、Kafka 等(官方插件列表)。
4.2 方式二:Docker 挂载 Agent
dockerfile
# Dockerfile
FROM openjdk:11-jre
COPY order-service.jar /app.jar
COPY skywalking-agent /skywalking/agent
ENV JAVA_TOOL_OPTIONS="-javaagent:/skywalking/agent/skywalking-agent.jar \
-Dskywalking.agent.service_name=order-service \
-Dskywalking.collector.backend_service=oap:11800"
ENTRYPOINT ["java", "-jar", "/app.jar"]
4.3 方式三:K8s Init Container 注入(推荐生产)
yaml
# 利用 init container 把 agent 拷贝到共享 volume
initContainers:
- name: init-skywalking-agent
image: apache/skywalking-java-agent:9.7.0-alpine
command: ["cp", "-r", "/skywalking/agent", "/shared/agent"]
volumeMounts:
- name: shared
mountPath: /shared
containers:
- name: order-service
image: order-service:latest
env:
- name: JAVA_TOOL_OPTIONS
value: >-
-javaagent:/shared/agent/skywalking-agent.jar
-Dskywalking.agent.service_name=order-service
-Dskywalking.collector.backend_service=oap:11800
volumeMounts:
- name: shared
mountPath: /shared
volumes:
- name: shared
emptyDir: {}
4.4 验证接入成功
bash
# 触发几次业务请求后,检查 agent 日志
tail -f /skywalking/agent/logs/skywalking-api.log
# 看到 "SkyWalking agent started" 且无报错即成功
# 在 UI 的 "Service" 页面应能看到 order-service
五、SkyWalking UI 实战:发现慢调用与异常链路
5.1 核心页面导航
| 页面 | 用途 |
|---|---|
| Dashboard | 全局指标:服务负载、慢服务排行、异常率 |
| Topology | 服务拓扑图(谁调谁,实时流量/耗时) |
| Trace Query | Trace 列表(按服务/耗时/状态码筛选) |
| Trace Detail | 链路详情(Span 树 + 耗时分布) |
| Alarm | 告警列表 |
5.2 发现慢调用:Trace 查询
操作路径:Trace → Trace Query
- Service: order-service
- Endpoint: POST:/api/order/create
- Min Duration: 2000ms ← 筛选 >2s 的慢调用
- Status: Error (可选,只看报错)
结果列表:
TraceID | Duration | Spans | Start Time
abc123... (订单创建) | 3210ms | 18 | 10:01:23
def456... (订单创建) | 2890ms | 18 | 10:01:25
→ 点击一条 Trace,进入详情。
5.3 分析 Trace 详情(关键技能)
订单创建 (3210ms) [order-service]
├── 校验用户 (45ms)
├── 查询库存 (2800ms) ⚠️ ← 瓶颈!占 87%
│ └── inventory-service
│ └── 查询库存DB (2750ms) ← 慢 SQL / 锁等待
├── 创建订单 (320ms)
└── 发送MQ (45ms)
从 Span 树能直接读出:
- 🔴 哪个 Span 最慢 :
查询库存DB 2750ms - 🔴 慢在哪个服务/实例 :
inventory-service / pod-ip-xxx - 🔴 慢的类型:DB 查询 / 外部调用 / 本地计算
→ 到此,SkyWalking 的使命完成:把问题定位到了「inventory-service 的数据库查询」。
5.4 把 TraceID 带到日志(打通 Logging)
关键一步 :让业务日志也打印 traceId,这样从 SkyWalking 发现 Trace 后能直接 grep 日志看上下文。
方式 :使用 SkyWalking 的 MDC 工具类(TraceContext)
java
// 在日志框架(Logback/Log4j2)的 pattern 中加入 traceId
// Logback 示例:logback-spring.xml
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%X{tid:-NONE}] [%thread] %-5level %logger - %msg%n</pattern>
java
// 代码中获取当前 traceId(用于自定义埋点/日志)
import org.apache.skywalking.apm.toolkit.trace.TraceContext;
String traceId = TraceContext.traceId();
log.info("处理订单, traceId={}", traceId);
💡 效果 :SkyWalking 看到慢 TraceID=
abc123,直接在 ELK/日志平台grep abc123就能看到这次请求在所有服务里的完整日志------Traces + Logs 打通。
六、从 Trace 到 Arthas:故障定位的桥梁
这是本文最核心的一节:SkyWalking 告诉你"哪个服务/方法慢",接下来用 Arthas 钻进去看"为什么慢"。
6.1 衔接的关键信息
从 SkyWalking Trace 详情中,我们能拿到:
| 信息 | 用途 |
|---|---|
| 服务名 | 确定目标服务 |
| 实例 IP / Pod | 确定 attach 哪个进程 |
| 慢 Span 对应的类名/方法名 | 确定 Arthas watch/trace 的目标 |
| TraceID | 关联日志、确认是同一次请求 |
6.2 实战:钻入慢方法
假设 SkyWalking 告诉我们 :inventory-service 的 InventoryDao.queryStock() 耗时 2750ms。
步骤:
bash
# ① 登录 inventory-service 所在 Pod
kubectl exec -it inventory-pod-xxx -- /bin/bash
# ② 找到 Java 进程 PID
jps | grep InventoryService
# 12345 InventoryServiceApplication
# ③ 启动 Arthas attach
java -jar arthas-boot.jar 12345
bash
# ④ 用 trace 看 InventoryDao.queryStock 的调用链耗时
$ trace com.example.inventory.dao.InventoryDao queryStock -j '#cost > 100' -n 20
输出:
`---ts=...; [cost=2750.2ms]
`---[1] com.example.inventory.dao.InventoryDao:queryStock()
+---[2] org.mybatis.spring.SqlSessionTemplate:selectOne() #cost=2720.5ms ⚠️
+---[3] com.example.inventory.cache.LocalCache:get() #cost=5.2ms
→ 确认瓶颈在 MyBatis 的 SQL 执行。
bash
# ⑤ 用 watch 看具体入参(是不是参数有问题导致全表扫)
$ watch com.example.inventory.dao.InventoryDao queryStock '{params, returnObj}' -x 3
输出:
params=[
@QueryStockReq([
skuId=@Long[123456],
warehouseId=null ← ⚠️ 可能为 null 导致未走索引!
])
]
→ 根因浮现 :warehouseId=null 导致 SQL 未命中索引,全表扫描 → 慢查询。
6.3 完整闭环示例
SkyWalking UI 发现下单 Trace 3.2s
│ 定位到 inventory-service.queryStock 慢 (2.75s)
▼
Arthas trace → 确认瓶颈在 MyBatis SQL (2.72s)
▼
Arthas watch → 发现入参 warehouseId=null
▼
根因:参数缺失 → SQL 未走索引 → 全表扫
▼
修复:代码补 warehouseId 校验 + 加索引
▼
回 SkyWalking → 验证 queryStock 耗时降到 20ms ✅
🎯 SkyWalking + Arthas 接力,从"发现慢"到"定位代码"全程 < 10 分钟。
七、实战案例:从「下单超时」到「定位具体代码」
案例 1:慢 SQL 导致下单超时
现象 :下单接口 P99 = 3.2s,SkyWalking 显示 查询库存DB 占比 87%。
排查:
# SkyWalking Trace → 定位 inventory-service.queryStock
# Arthas 钻入:
$ trace ... queryStock -j '#cost > 500'
→ 瓶颈: SqlSessionTemplate.selectOne 2720ms
$ watch ... queryStock '{params}' -x 3
→ 发现 warehouseId=null,疑似未走索引
# 到 DB 验证
EXPLAIN SELECT * FROM inventory WHERE sku_id=123456 AND warehouse_id IS NULL;
→ type=ALL (全表扫) ❌
修复 :业务层校验 warehouseId 必填 + 联合索引 (sku_id, warehouse_id)。
案例 2:下游服务超时雪崩
现象 :订单服务报错 Read timed out,但自身 CPU 正常。
SkyWalking :Topology 图发现 order-service → coupon-service 红线(超时),coupon-service 响应 5s+。
Trace 详情:
订单创建 (5200ms)
├── 校验 (20ms)
├── 调优惠券 (5000ms) ⚠️ → coupon-service
│ └── coupon-service: 内部处理 (4980ms) → 其 DB 慢
└── ...
Arthas :登录 coupon-service Pod → thread -n 5 发现大量线程 BLOCKED 在获取数据库连接池 → 连接池耗尽。
根因 :优惠券服务 DB 连接池太小 + 慢查询占连接 ,雪崩到上游。
修复 :调大连接池 + 慢 SQL 优化 + 订单服务加 熔断降级(Sentinel/Resilience4j)。
案例 3:偶发超时 ------ 靠 TraceID 精准捕获
现象:超时只偶发(每天几次),jstack 抓不到。
策略 :利用 SkyWalking 的 告警 webhook 或 Trace 查询按 duration 筛选 ,抓到慢 Trace 后立即记录 TraceID,再用 Arthas tt 回放该请求的调用。
# SkyWalking 告警触发 → 记录 TraceID=abc123
# 到对应 Pod 用 Arthas tt 录制/回放(需提前埋点)
$ tt -t com.example.inventory.dao.InventoryDao queryStock -n 1000
$ tt -l | grep abc123 # 找到该 Trace 对应的调用记录
$ tt -i <index> # 回放入参/返回值/耗时
→ 把"偶发"变成"可回放",这是单机工具做不到的。
八、高级技巧:自定义标签、告警与日志关联
8.1 自定义 Tag / Log(增强 Trace 信息)
java
import org.apache.skywalking.apm.toolkit.trace.Trace;
import org.apache.skywalking.apm.toolkit.trace.Tag;
// ① 方法级 Trace(把业务方法也纳入链路)
@Trace(operationName = "createOrder")
@Tag(key = "userId", value = "arg[0].userId")
@Tag(key = "amount", value = "arg[0].amount")
public OrderResult createOrder(OrderReq req) {
// ...
}
// ② 手动获取/打印 traceId(打通日志)
String traceId = TraceContext.traceId();
log.info("order created, traceId={}", traceId);
→ 业务参数(userId/amount)会出现在 SkyWalking Span 的 Tag 里,排查时能直接看到"哪个用户的订单慢"。
8.2 告警规则(alarm-settings.yml)
yaml
# config/alarm-settings.yml
rules:
service_resp_time_rule:
metrics-name: service_resp_time
op: ">"
threshold: 2000 # 响应时间 > 2s
period: 10
count: 3
silence-period: 60
message: "服务 {name} 平均响应时间超过 2s (最近 10 分钟 3 次)"
service_error_rate_rule:
metrics-name: service_error_rate
threshold: 0.5 # 错误率 > 50%
period: 10
count: 2
message: "服务 {name} 错误率超 50%"
# webhook 推送到企业微信/钉钉
webhooks:
- http://your-webhook/notify
→ 慢调用自动告警 → 触发人拿着 TraceID 去 Arthas 排查,形成自动化闭环。
8.3 日志 + Trace 关联(ELK 打通)
SkyWalking TraceID
│
▼ (MDC 写入日志)
应用日志 [traceId=abc123] ...
│
▼ (Filebeat 采集)
Elasticsearch
│
▼
Kibana:按 traceId 聚合一次请求的跨服务日志
配置(Logback):
xml
<encoder>
<pattern>%d %X{tid:-NONE} [%thread] %level %logger - %msg%n</pattern>
</encoder>
💡 效果 :在 SkyWalking 点开任意 Span → 直接跳转 Kibana 查看该 TraceID 的全链路日志,无需人工 grep。
九、SkyWalking vs 竞品选型
| 维度 | SkyWalking | Zipkin | Jaeger | Pinpoint |
|---|---|---|---|---|
| 国产/社区 | Apache 顶级,国产 | Twitter 开源 | CNCF | Naver |
| 自动探针 | ✅ 丰富(Java 生态强) | ⚠️ 一般 | ✅ | ✅ |
| 性能指标 | ✅ 强(APM 一体) | ⚠️ 偏 Trace | ⚠️ 偏 Trace | ✅ |
| 拓扑图 | ✅ 实时 | ❌ | ⚠️ | ✅ |
| 告警 | ✅ 内置 | ❌ | ⚠️ | ✅ |
| 日志关联 | ✅ | ⚠️ | ⚠️ | ⚠️ |
| 存储 | ES/H2/MySQL/TiDB | ES/Cassandra | ES/Cassandra | HBase |
| Java 微服务 | ⭐ 首选 | 轻量场景 | Go/云原生 | Java |
💡 选型建议:
- Java/Spring Cloud 微服务为主 → SkyWalking 首选(探针最全、APM 一体、国产友好、中文文档丰富)
- 纯云原生/多语言(Go/Rust) → Jaeger(CNCF 生态)
- 已有 Zipkin 埋点 → 沿用 Zipkin(兼容 OpenTracing)
十、生产最佳实践与常见坑
10.1 采样率控制(关键!)
⚠️ 全量采集 Trace 在 QPS 高时会撑爆存储 + 拖慢应用。
yaml
# agent.config
agent.sample_n_per_3_secs=10 # 每 3 秒采样 10 条 Trace
# 或按比例:
agent.sample_percentage=10 # 采样 10%
策略:
- 正常时期:低采样(1%~10%)
- 异常时期 :通过 SkyWalking 动态调高采样(UI → 配置 → 采样率),捕获更多细节
10.2 性能开销
- SkyWalking Agent 正常开销 < 5% ,但:
- ❌ 避免采集 高频内部方法 (用
trace.ignore_path排除健康检查等) - ✅ 合理设置采样率
- ❌ 避免采集 高频内部方法 (用
- Arthas 仅在排查时临时 attach,用完即
stop卸载
10.3 常见坑
| 坑 | 解决方案 |
|---|---|
| Trace 断链(跨线程/异步丢失) | 使用 @TraceCrossThread 或手动 ContextManager 传递 |
| 探针版本不兼容 | Agent 版本 ≤ OAP 版本(向后兼容) |
| agent 启动失败 | 检查 -javaagent 路径、权限、JDK 版本 |
| 存储爆满 | 设置 ES 索引生命周期(ILM)+ TTL |
| Span 太多 | 排除健康检查、内部探活接口 |
| 容器 IP 显示为 Pod IP | 配置 agent.instance_name 用 hostname |
十一、容器与 Kubernetes 部署
11.1 OAP + UI 部署(Helm 推荐)
bash
# 添加 SkyWalking Helm 仓库
helm repo add skywalking https://apache.jfrog.io/artifactory/skywalking-helm
helm repo update
# 安装(默认 ES 为存储)
helm install skywalking skywalking/skywalking \
--set oap.storageType=elasticsearch \
--set elasticsearch.enabled=true \
--namespace observability \
--create-namespace
11.2 Java 微服务接入(Sidecar / Init Container)
推荐 Init Container 拷贝 Agent(第四节方式三),避免每个镜像都打包 agent。
关键 K8s 配置:
yaml
env:
- name: SW_AGENT_NAME
valueFrom:
fieldRef:
fieldPath: metadata.labels['app'] # 用 Pod label 做服务名
- name: SW_AGENT_COLLECTOR_BACKEND_SERVICES
value: "skywalking-oap:11800"
11.3 与 Arthas 的 K8s 协作
bash
# 1. SkyWalking UI 发现慢调用 → 定位到 Pod
# 2. kubectl debug 进入该 Pod(临时诊断容器,共享 pid)
kubectl debug -it <pod> --image=arthas/arthas:latest --target=<container>
# 3. 在临时容器内 attach 到业务进程
java -jar arthas-boot.jar 1
# 4. 用 TraceID 关联:arthas 里用 tt/watch 过滤该 Trace 的请求
$ watch ... method '{params}' '#cost > 1000'
附:命令 / 配置速查表
SkyWalking 部署 / 运维
| 命令/配置 | 作用 |
|---|---|
docker compose up -d |
一键启动 OAP+UI+ES |
curl localhost:12800/health check |
检查 OAP 健康 |
SW_STORAGE=elasticsearch |
指定存储为 ES |
SW_STORAGE_ES_CLUSTER_NODES=es:9200 |
ES 地址 |
Java Agent 配置
| 参数 | 作用 |
|---|---|
-javaagent:.../skywalking-agent.jar |
挂载探针 |
service_name |
服务名 |
backend_service=oap:11800 |
OAP gRPC 地址 |
sample_n_per_3_secs=10 |
采样率 |
instance_name=${HOSTNAME} |
实例名(用 Pod hostname) |
Trace 查询 / 分析
| 操作 | 说明 |
|---|---|
| Trace Query 按 duration 筛选 | 找慢调用 |
| Trace Detail Span 树 | 看耗时分布、定位慢 Span |
| Topology 图 | 看服务依赖、红线异常 |
打通日志
| 方式 | 说明 |
|---|---|
TraceContext.traceId() |
代码获取 traceId |
MDC %X{tid} |
日志 pattern 打印 traceId |
@Trace / @Tag |
自定义埋点 + 业务 Tag |
SkyWalking → Arthas 衔接
| 步骤 | 命令 |
|---|---|
| 从 Trace 拿到服务/Pod/方法 | SkyWalking UI |
| 登录 Pod | kubectl exec / kubectl debug |
| attach 进程 | arthas-boot.jar <PID> |
| 钻入慢方法 | trace class method -j '#cost > 100' |
| 看入参返回值 | watch class method '{params, returnObj}' -x 3 |
| 回放调用 | tt -t ... / tt -i <index> |
告警(alarm-settings.yml)
| 字段 | 含义 |
|---|---|
metrics-name |
指标名(resp_time/error_rate) |
threshold |
阈值 |
period / count |
时间窗口 / 触发次数 |
webhooks |
告警推送地址 |
结语
SkyWalking + Arthas 的组合,本质是「望远镜 + 显微镜」:
- 🔭 SkyWalking(望远镜) :宏观看 哪个服务、哪个链路、哪个 Span 慢,把排查范围从"整个集群"收敛到"一个方法"
- 🔬 Arthas(显微镜) :微观看 这个方法的入参、返回值、耗时、调用链,直接定位到代码行
记住这个闭环:
SkyWalking 发现慢 Trace
→ 定位服务/Pod/方法
→ Arthas 钻入确诊
→ 修复
→ SkyWalking 验证恢复
掌握这套组合,你就具备了「从用户投诉到代码根因」的分钟级诊断能力 ------这是高级测试工程师 / SDET / 性能诊断工程师 的核心竞争力。
三者进阶路线:
- 🟢 Linux 命令:看资源(CPU/内存/网络)------ 基础
- 🟡 三剑客 (jstack/jmap/jstat):看单机 JVM 快照 ------ 进阶
- 🟠 Arthas:在线动态诊断 ------ 高阶
- 🔴 SkyWalking + Arthas :全链路诊断 ------ 专家级 🏆
本文命令在 SkyWalking 9.x + Spring Boot 2.x/3.x + JDK 8/11/17 下验证通过。生产环境务必配置采样率与存储 TTL;Arthas 排查完执行 stop 卸载 agent。