Apache SkyWalking —— 国产开源一体化 APM:无侵入探针 + OAP 分析 + 拓扑/链路/指标/告警
Apache SkyWalking —— 国产开源一体化 APM:无侵入探针 + OAP 分析 + 拓扑/链路/指标/告警
分类:05 APM与链路追踪 适用:Java / Go / Python / Node.js / .NET 等多语言微服务、Service Mesh、K8s 云原生与混合云;单机 PoC 到数百服务大规模集群 一句话:Language Agent 自动埋点 → OAP 接收/聚合 → 可插拔存储 → UI 拓扑/链路/指标与告警,四件事收在一个平台 官方:https://skywalking.apache.org/ | https://github.com/apache/skywalking 授权:Apache License 2.0(Apache 软件基金会顶级项目,开源免费、可商用)
版本说明:官方 main 分支已到 11.x(可查 v11.0.0 Backend setup 文档),新 UI 代号 Horizon;Java/Go/Python/Node.js Agent 为独立仓库、独立发版。本文镜像 tag、发行包版本一律写「以官方最新稳定版为准」,不锁定具体数字。
1. 它解决什么问题
| 痛点 | 做法 |
|---|---|
| 微服务调用链黑盒,慢调用靠猜 | 探针自动生成 Trace/Span,UI 出瀑布图、服务拓扑、上下游依赖 |
| 改业务代码埋点成本高、语言杂 | 字节码增强/编译期注入,Java 等无侵入,官网列出 11 类语言 Agent |
| 指标、日志、链路三套系统来回切 | TraceID 贯通日志;OAP 内置 MAL/MQE 指标、Log、Profiling、告警 |
| 不想为看链路引入整套 ES 运维 | 存储可插拔,官方推荐原生 BanyanDB;也支持 ES/OpenSearch、MySQL/PostgreSQL |
| 告警散落 / K8s 不便挂探针 | 内置 alarm(MQE 规则)+ hooks;eBPF(Rover)、Sidecar 注入(SWCK)、OTLP 直连 |
不适合:只需纯链路且已全面 OTel 化(Jaeger/Tempo 更轻);只要基础设施指标(Prometheus 系);需闭源商业支持;无法承担 OAP + 有状态存储运维的小团队。OAP 是有状态分析集群,不是无状态采集器。
2. 核心概念与架构
| 术语 | 含义 |
|---|---|
| Agent / Probe | 语言探针,随应用启动自动拦截框架调用生成 TraceSegment;Java 用 -javaagent 字节码增强 |
| TraceSegment | 进程内一次请求的 Span 集合,跨进程用 Context(sw8 / W3C traceparent)串成 Trace |
| Service / Instance / Endpoint | 服务(逻辑组)/ 实例(唯一节点)/ 端点(URL、RPC 方法)三层元数据 |
| OAP / Receiver | 后端:注册、接收、OAL/MAL 聚合、告警计算、GraphQL 查询;接收模块含 gRPC(Agent/OTLP/ALS)、HTTP、Zipkin、Kafka、Zabbix |
| Storage / UI | BanyanDB(默认推荐)/ ES / OpenSearch / MySQL / PG / H2(仅演示);UI 经 GraphQL over HTTP :12800 查 OAP,自身 :8080 |
| OAL / MAL / MQE / Layer / TTL | 指标定义 / 计量脚本 / 指标查询表达式(告警用 MQE);逻辑分层(GENERAL/MESH/K8S…)、按记录类型配置保留天数 |
应用(无侵入) ┌──────── OAP 集群 ────────┐ 存储 / 消费
┌──────────────┐ gRPC │ Receivers(:11800 gRPC) │ ┌─────────────────┐
│ Java Agent │─────►│ agent/OTLP/Zipkin/ALS │ 写 │ BanyanDB :17912 │
│ Go/Python/Node│ sw8 │ Analyze: OAL/MAL 聚合 │────►│ (默认推荐) │
│ .NET/PHP/Rust…│─────►│ Alarm: MQE 规则 │ │ ES/OpenSearch │
│ Rover(eBPF) │ OTLP │ Query: GraphQL(:12800)│ │ MySQL/PostgreSQL│
└──────────────┘ └───────────┬───────────┘ └────────┬────────┘
▼ │ 读
┌──────────────────┐ HTTP ┌───────────────────┐
│ UI :8080 │◄─────│ 告警 hooks → │
│ 拓扑/链路/仪表盘 │ │ Webhook/企业微信 │
└──────────────────┘ └───────────────────┘
链路:Agent 埋点 → OAP 接收/分析 → Storage 落盘 ← UI 查询 → Alarm 推送。Agent 与 OAP 走 :11800 gRPC(OTLP、Envoy ALS、eBPF、Satellite 共享);UI/运维查 :12800 GraphQL,二者勿混。OAP 先把 TraceSegment 注册成 Service/Instance/Endpoint 字典再聚合,故首次接入需等 1~2 个采集周期。
探针语言支持(官网 ECOSYSTEM「11 language agents」,各仓库独立发版)
| 语言/形态 | 接入方式 | 备注 |
|---|---|---|
| Java(skywalking-java)/ Go(skywalking-go) | -javaagent / go build -toolexec |
Java 插件最全(Spring/Dubbo/JDBC/MQ);Go 需改构建命令 |
| Python / Node.js / .NET / PHP / Rust / Ruby / Lua / C++ | pip 包 / npm / 各自 SDK | 覆盖度低于 Java,以各仓库 README 为准 |
| Client JavaScript / eBPF(Rover) | 浏览器 SDK / K8s DaemonSet | 前端 RUM;无语言侵入的网络/CPU Profiling |
3. 安装与部署
3.1 环境准备
| 项 | 要求 |
|---|---|
| Java(OAP/UI) | JDK 11 / 17 / 21 / 25;发行包按 Java 11 编译(最小运行时)。Agent 端 JDK 以其仓库说明为准 |
| 存储 / 端口 | 推荐 BanyanDB,或 ES 7/8、OpenSearch、MySQL/PostgreSQL;H2 仅演示。OAP :11800 gRPC(Agent/OTLP)、:12800 HTTP(GraphQL/health);UI :8080(回连 127.0.0.1:12800);BanyanDB :17912 gRPC / :17913 HTTP |
| 内核 / 容器运行时权限 | Linux,cgroup 仅 eBPF 探针相关;OAP/UI/存储无需特权、非 root 运行;Rover(eBPF) 需 privileged + hostPID;全节点 NTP |
| OAP 11 附加端口 / 资源 | :17128 admin、:9090 PromQL、:3100 LogQL、:3200 TraceQL、:1234 自监控(以官方 Helm/发行包为准,10.x 无 admin-server);OAP ≥4 vCPU/8 GB 起步,官方 BanyanDB 基准 2 liaison + 2 data(各 4 vCPU/8 GB)承载约 200 服务 / 200+ cps |
3.2 多种安装方式
# 版本号、镜像 tag 一律以官方最新稳定版为准
export SW_VER=<以官方最新稳定版为准>
export BYDB_VER=<与 OAP 兼容的 BanyanDB Server 版本,见 4.4>
# A. 官方二进制包(物理机/VM):从 https://skywalking.apache.org/downloads/ 下载 apache-skywalking-apm-<SW_VER>.tar.gz
tar -xzf apache-skywalking-apm-${SW_VER}.tar.gz && cd apache-skywalking-apm-${SW_VER}
ls config/application.yml config/alarm-settings.yml webapp/webapp.yml bin/startup.sh
bin/startup.sh # OAP + UI;分开用 bin/oapService.sh / bin/webappService.sh
# B. Docker 独立容器(依次起存储 → OAP → UI)
docker run -d --name banyandb -p 17912:17912 -p 17913:17913 apache/skywalking-banyandb:${BYDB_VER} standalone
docker run -d --name oap -p 11800:11800 -p 12800:12800 \
-e SW_STORAGE=banyandb -e SW_STORAGE_BANYANDB_TARGETS=<BanyanDB_HOST>:17912 \
-e SW_CLUSTER=standalone apache/skywalking-oap-server:${SW_VER}
docker run -d --name ui -p 8080:8080 -e SW_OAP_ADDRESS=http://<OAP_HOST>:12800 apache/skywalking-ui:${SW_VER}
# C. K8s Helm(官方 chart,版本以官方最新稳定版为准)
helm install skywalking oci://docker.io/apache/skywalking-helm --version <chart版本> \
--set oap.image.tag=<SW_VER> --set oap.storageType=banyandb \
--set elasticsearch.enabled=false --set banyandb.enabled=true \
--set banyandb.image.tag=<BYDB_VER> --set ui.image.tag=<SW_VER>
kubectl get svc,pod -l app=skywalking # K8s 另可用 SWCK Java Agent Injector 挂 sidecar
D. Docker Compose(推荐,一键全套)
# docker-compose.yaml —— tag 以官方最新稳定版为准
services:
banyandb:
image: apache/skywalking-banyandb:${BYDB_VER}
command: standalone
ports: ["17912:17912", "17913:17913"]
oap:
image: apache/skywalking-oap-server:${SW_VER}
environment:
SW_STORAGE: banyandb
SW_STORAGE_BANYANDB_TARGETS: banyandb:17912
SW_CLUSTER: standalone
SW_OTEL_RECEIVER: default
SW_OTEL_RECEIVER_ENABLED_OC_RULES: vm
ports: ["11800:11800", "12800:12800"]
depends_on: [banyandb]
ui:
image: apache/skywalking-ui:${SW_VER}
environment: { SW_OAP_ADDRESS: http://oap:12800 }
ports: ["8080:8080"]
E. 二进制 + systemd(生产托管)
# /etc/systemd/system/skywalking-oap.service
[Service]
Type=forking
User=skywalking
Environment=SW_STORAGE=banyandb
Environment=SW_STORAGE_BANYANDB_TARGETS=<BanyanDB_HOST>:17912
Environment=SW_CLUSTER=standalone
ExecStart=/opt/skywalking/bin/oapService.sh
Restart=on-failure
[Install]
WantedBy=multi-user.target
docker compose up -d && docker compose ps # D 启动
systemctl daemon-reload && systemctl enable --now skywalking-oap # E 启动(UI 另建 unit)
# 官方另有 skywalking-showcase 与 BanyanDB 仓库内 compose 演示栈(含 demo 微服务)
3.3 首次启动与验证
curl -sS -w '\nHTTP %{http_code}\n' http://<OAP_HOST>:12800/healthcheck # 预期 HTTP 200
curl -sS -X POST http://<OAP_HOST>:12800/graphql -H 'Content-Type: application/json' \
-d '{"query":"query { version getTimeInfo { timezone currentTimestamp } checkHealth { score details } }"}'
# 预期 {"data":{"version":"<构建串>",...,"checkHealth":{"score":0,...}}};score=0 为 OK,>0 为 degraded
curl -sS -o /dev/null -w 'UI HTTP %{http_code}\n' http://<UI_HOST>:8080/ # 预期 200,浏览器可见(空)服务列表
grep -E 'Version|module.core.provider|module.storage.provider' logs/skywalking-oap-server.log # 预期 booting parameters 模块表
4. 配置文件详解
4.1 主配置路径
| 文件 | 作用 |
|---|---|
config/application.yml |
OAP 主配置:cluster/core/storage/receiver/query/alarm/telemetry 的 selector 与参数 |
config/alarm-settings.yml |
告警规则(MQE 表达式)与 hooks 通知目标 |
config/log4j2.xml(旧版 log4j.xml) |
OAP 日志级别与滚动 |
config/bydb.yml |
BanyanDB 专属参数,含 SW_STORAGE_BANYANDB_COMPATIBLE_SERVER_API_VERSIONS |
webapp/webapp.yml / skywalking-agent/config/agent.config |
UI 端口与 oapServices;Java Agent 配置(随应用分发) |
多数项支持
SW_*环境变量覆盖(优先级高于文件);生产用环境变量,不改包内文件便于镜像复用。
4.2 关键项说明表
| 配置项 / 环境变量 | 默认 | 说明 |
|---|---|---|
storage.selector / SW_STORAGE |
banyandb |
banyandb/elasticsearch/opensearch/mysql/postgresql/h2 |
SW_STORAGE_BANYANDB_TARGETS |
127.0.0.1:17912 |
BanyanDB gRPC 地址,多个逗号分隔 |
SW_STORAGE_BANYANDB_COMPATIBLE_SERVER_API_VERSIONS |
见 bydb.yml |
OAP ↔ BanyanDB 版本兼容锁,见 4.4 |
SW_CLUSTER |
standalone |
standalone/zookeeper/kubernetes/consul/etcd/nacos |
SW_CORE_REST_HOST / SW_CORE_REST_PORT |
0.0.0.0/12800 |
GraphQL 与 HTTP receiver |
SW_CORE_GRPC_HOST / SW_CORE_GRPC_PORT |
0.0.0.0/11800 |
Agent / OTLP gRPC |
SW_RECEIVER_GRPC_PORT / SW_RECEIVER_SHARING_REST_PORT |
0(回落 core 端口) |
单独给 receiver 开端口时设非 0 |
SW_TELEMETRY / SW_OTEL_RECEIVER / SW_OAP_ADDRESS / core.default.*DataTTL |
prometheus / default / http://127.0.0.1:12800 / 指标 7 天、记录 3 天(示例) |
自监控 :1234;OTLP 接收;UI 回连;保留期以所用版本为准 |
4.3 完整可运行最小示例:Java Agent agent.config
分发目录 skywalking-agent/:skywalking-agent.jar、config/agent.config、plugins/、optional-plugins/、logs/;插件 jar 移入/移出 plugins/ 即启用/禁用。
# skywalking-agent/config/agent.config —— 最小可用
agent.service_name=${SW_AGENT_NAME:Your_ApplicationName} # UI 服务名,全局唯一
collector.backend_service=${SW_AGENT_COLLECTOR_BACKEND_SERVICES:127.0.0.1:11800} # OAP gRPC,非 12800
agent.namespace=${SW_AGENT_NAMESPACE:} # 隔离传播 header
agent.instance_name=${SW_AGENT_INSTANCE_NAME:} # 留空则 UUID@hostname 生成
agent.sample_n_per_3_secs=${SW_AGENT_SAMPLE:-1} # 每 3 秒最多 N 段;<=0 关闭
agent.span_limit_per_segment=${SW_AGENT_SPAN_LIMIT:300} # 单 Segment 最大 Span
agent.ignore_suffix=${SW_AGENT_IGNORE_SUFFIX:.jpg,.js,.css,.png,/health,/actuator/health}
logging.level=${SW_LOGGING_LEVEL:INFO}
logging.file_name=${SW_LOGGING_FILE_NAME:skywalking-api.log}
logging.dir=${SW_LOGGING_DIR:}
覆盖优先级:
-Dskywalking.<key>>SW_AGENT_*环境变量 >agent.config文件值;生产推荐只用环境变量。
4.4 OAP 配置片段与「存储后端版本差异」(重要)
application.yml 不建议全量手写,只覆盖 selector 与端口(selector 写法取自官方 storage 文档):
# config/application.yml —— 片段,非全量文件
storage:
selector: ${SW_STORAGE:banyandb}
banyandb:
targets: ${SW_STORAGE_BANYANDB_TARGETS:127.0.0.1:17912}
cluster:
selector: ${SW_CLUSTER:standalone}
standalone: {}
core: # core.default 另含 restHost/gRPCHost,默认 0.0.0.0
selector: ${SW_CORE:default}
default:
restPort: ${SW_CORE_REST_PORT:12800}
gRPCPort: ${SW_CORE_GRPC_PORT:11800}
| 存储后端 | 适用场景 | 版本/成本注意点 |
|---|---|---|
| BanyanDB(默认推荐) | 大规模 Trace/Log/Measure | 必须配套 OAP 大版本:config/bydb.yml 的 SW_STORAGE_BANYANDB_COMPATIBLE_SERVER_API_VERSIONS 声明兼容 API 版本,再按官方 API 版本映射选 BanyanDB Server;OAP 10.x/11.x 对应 BanyanDB 版本不同,跨大版本混用写入失败 |
| ES 7/8 / OpenSearch | 大规模生产 | ES 内存与副本成本高、不同 OAP 版本支持的 ES 主版本不同;OpenSearch 自 ES 7.10.2 分叉,索引模板不通用 |
| MySQL/PostgreSQL(含 TiDB、Aurora) | 中等规模、低采样率 | Trace/Log 写入性能显著低于 BanyanDB/ES,且不能靠加节点线性扩展 |
| H2 | 仅本地演示/CI | 重启即丢、不可集群,⚠️ 禁止生产 |
⚠️ 升级顺序:先确认 bydb.yml 兼容 API 版本 → 选匹配 BanyanDB Server → 升 OAP → 升 UI → 升 Agent。只升 OAP 不换 BanyanDB 是常见事故。
4.5 完整可运行最小示例:alarm-settings.yml
# config/alarm-settings.yml —— 规则 id 必须以 _rule 结尾
rules:
service_resp_time_rule:
# MQE:根运算必须比较运算,结果 1(true) 即触发
expression: sum(service_resp_time > 1000) >= 3
period: 10
silence-period: 5
recovery-observation-period: 3
message: 服务 {name} 在最近 10 分钟内有 3 分钟响应时间超过 1000ms
完整规则集(含
service_sla_rule与hooks.webhook/hooks.wechat)见第 6 章。8.x 及更早用metrics-name/op/threshold/period/count/silence-period;9.x+ 改为 MQEexpression。跨大版本升级必须按新版自带alarm-settings.yml重写规则,否则旧规则被忽略或启动报错。
5. 核心使用方法
5.1 命令集(编号 122 命令 + 2326 UI 路径 + 指标表,共 ≥26 条)
# --- Java Agent 挂载(无侵入)---
# 1) 标准 Spring Boot:-javaagent 必须在 -jar 之前
java -javaagent:/opt/skywalking-agent/skywalking-agent.jar \
-Dskywalking.agent.service_name=order-service \
-Dskywalking.collector.backend_service=<OAP_HOST>:11800 -jar order-service.jar
# 2) 纯环境变量(容器推荐)
export SW_AGENT_NAME=order-service SW_AGENT_COLLECTOR_BACKEND_SERVICES=<OAP_HOST>:11800
export JAVA_TOOL_OPTIONS="-javaagent:/opt/skywalking-agent/skywalking-agent.jar"
java -jar order-service.jar
# 3) Tomcat:bin/catalina.sh 首行加
CATALINA_OPTS="$CATALINA_OPTS -javaagent:/opt/skywalking-agent/skywalking-agent.jar"; export CATALINA_OPTS
# 4) 采样与 Span 上限:-Dskywalking.agent.sample_n_per_3_secs=10 -Dskywalking.agent.span_limit_per_segment=300
# 5) 日志输出 TraceID:应用引 apm-toolkit-logback/log4j,pattern 加 %tid(版本以官方为准)
# 6) Docker 只读挂载探针
docker run -v /opt/skywalking-agent:/skywalking-agent:ro \
-e SW_AGENT_NAME=order-service -e SW_AGENT_COLLECTOR_BACKEND_SERVICES=<OAP_HOST>:11800 \
-e JAVA_TOOL_OPTIONS=-javaagent:/skywalking-agent/skywalking-agent.jar <业务镜像:tag>
# --- OAP REST :12800 ---
# 7) 健康检查
curl -sS http://<OAP_HOST>:12800/healthcheck
# 8) 版本 + 健康分
curl -sS -X POST http://<OAP_HOST>:12800/graphql -H 'Content-Type: application/json' \
-d '{"query":"query { version getTimeInfo { timezone currentTimestamp } checkHealth { score details } }"}'
# 9) 服务列表(V1 API 自 9.5.0 deprecated 但短期兼容;Duration 格式 "yyyy-MM-dd HHmm")
curl -sS -X POST http://<OAP_HOST>:12800/graphql -H 'Content-Type: application/json' \
-d '{"query":"query ($d: Duration!) { services: getAllServices(duration: $d) { id name normal } }",
"variables":{"d":{"start":"2026-11-05 0000","end":"2026-11-05 0100","step":"MINUTE"}}}'
# 10) 服务实例 / 11) 指标时序同理:getServiceInstances(duration,serviceId)、readMetricsValues(condition,duration);或用 swctl 19)
# 12) OTLP 直连 OAP(无需 SkyWalking Agent)
export OTEL_EXPORTER_OTLP_ENDPOINT=http://<OAP_HOST>:11800 OTEL_SERVICE_NAME=payment-service
export OTEL_TRACES_SAMPLER=parentbased_traceidratio OTEL_TRACES_SAMPLER_ARG=0.1
# --- swctl(SkyWalking CLI)---
# 13) 指定 OAP 地址
export SWCTL_BASE_URL=http://<OAP_HOST>:12800/graphql
swctl service list # 14) 服务列表
swctl instance list --service-name=order-service # 15) 实例列表
swctl endpoint list --service-name=order-service # 16) 端点列表
swctl trace list --service-name=order-service # 17) 最近 Trace
swctl trace <trace-id> # 18) 单条 Trace 详情
swctl metrics linear --name=service_resp_time --service-name=order-service # 19) 指标折线
swctl logs list --service-name=order-service # 20) 关联日志
swctl dashboard global # 21) 全局仪表盘
swctl --base-url=http://<OAP_HOST>:12800/graphql --display yaml service list # 22) YAML 输出
5.2 Web UI 路径(23~26)与常用指标
| # | 目标 / 路径 |
|---|---|
| 23 | 服务 SLA/CPM/RT:General → Service;调用拓扑:General → Topology |
| 24 | 定位慢调用:Trace → 按服务/耗时/状态过滤 → 点 TraceID 看瀑布图 |
| 25~26 | 指标 Dashboard → Service;告警 Alarm;JVM General → Instance;日志 Log(按 TraceID 反查);Profiling Profile → 火焰图 |
| 指标 | 含义 / 用途 |
|---|---|
service_resp_time / service_sla / service_cpm |
平均 RT(ms) / 成功率(×100,8000=80%)/ 每分钟调用数;慢调用、可用性、流量突降告警 |
service_percentile / service_instance_resp_time / endpoint_resp_time |
p50~p99 长尾 / 实例 RT / 端点 RT;单机故障、接口瓶颈 |
endpoint_cpm / endpoint_relation_resp_time / database_access_resp_time / _sla / instance_jvm_* / service_apdex |
端点吞吐、端点间调用、DB 调用;依赖链路与慢 SQL;JVM 堆/GC、Apdex、SLO |
告警规则入口 config/alarm-settings.yml(4.5、第 6 章):常用 service_resp_time_rule、service_sla_rule、service_resp_time_percentile_rule、service_instance_resp_time_rule、database_access_resp_time_rule。
6. 告警与通知
噪声控制:period(评估窗口分钟)、silence-period(触发后静默,抑制风暴)、recovery-observation-period(连续 N 周期不触发才判恢复,消除抖动)、sum(<metric> <op> <阈值>) >= <次数>(N 分钟内 M 次异常才告警)。
# config/alarm-settings.yml:分层规则 + 多通道通知
rules:
endpoint_slow_rule:
expression: sum(endpoint_resp_time > 3000) >= 3
period: 10
silence-period: 10
recovery-observation-period: 5
message: 端点 {name} 连续慢响应
hooks:
webhook: # 通用 Webhook(可转发钉钉/飞书/邮件网关)
default:
is-default: true
urls: [http://<告警网关_HOST>:<PORT>/skywalking/alarm]
wechat: # 企业微信(官方模板内置 wechat hook)
text-template: |-
{"msgtype":"text","text":{"content":"Apache SkyWalking 告警:\n %s."}}
webhooks:
- https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=<企业微信机器人key>
# 告警体 JSON(scope/name/ruleName/alarmMessage/startTime)由网关格式化转发;邮件则交 SMTP Relay 发送
# 钉钉
curl -sS -X POST 'https://<钉钉机器人Webhook URL>' -H 'Content-Type: application/json' -d '{"msgtype":"text","text":{"content":"SkyWalking 告警:<alarmMessage>"}}'
其他 hook(gRPCHook、Slack、飞书、DingTalk、邮件等)以所用版本
alarm-settings.yml注释模板与官方告警文档为准,不同大版本支持的 hook 名不完全一致。降噪:按服务分层设阈值;silence-period ≥ period;网关按ruleName + name去重与认领;夜间非 P0 走聚合摘要。
7. 实战场景
7.1 接入一个 Java 服务(无侵入 Agent)
- 目标:不改一行业务代码,让
order-service出现在 UI 并产生链路。步骤:准备 agent 目录 → 设服务名与 OAP 地址 → 挂载启动 → 造流量。
export SW_AGENT_NAME=order-service SW_AGENT_COLLECTOR_BACKEND_SERVICES=<OAP_HOST>:11800 SW_AGENT_SAMPLE=-1
java -javaagent:/opt/skywalking-agent/skywalking-agent.jar \
-Dskywalking.logging.file_name=skywalking-api.log -jar /app/order-service.jar
for i in $(seq 1 50); do curl -sS http://localhost:8081/api/orders/1 -o /dev/null; done
- 验证:
swctl service list出现order-service;UIGeneral → Service有 CPM/RT;Trace有瀑布图。 - 回滚:去掉
-javaagent与SW_AGENT_*重启应用即可,探针不写业务数据、无残留;⚠️JAVA_TOOL_OPTIONS是全局环境变量,回滚时务必一并清理,否则所有 JVM 都会被挂探针。
7.2 定位一次慢调用
- 目标:下单接口偶发 >2s,定位到具体服务/端点/SQL。步骤:缩时间窗 → Trace 按耗时排序 → 看 Span 瀑布 → 下钻指标 → 加告警。
# 1) 近 1 小时 RT 时序
swctl --base-url=http://<OAP_HOST>:12800/graphql --display yaml \
metrics linear --name=service_resp_time --service-name=order-service
# 2) GraphQL 查 p99,判断长尾还是整体变慢
curl -sS -X POST http://<OAP_HOST>:12800/graphql -H 'Content-Type: application/json' \
-d '{"query":"query ($d: Duration!) { readMetricsValues(condition: {name: \"service_percentile\", entity: {scope: Service, serviceName: \"order-service\", normal: true}}, duration: $d) { label values { values { value } } } }",
"variables":{"d":{"start":"2026-11-05 1000","end":"2026-11-05 1100","step":"MINUTE"}}}'
# 3) 列最近 Trace 找耗时最大的 TraceID;4) 看 Span 明细定位 DB 还是下游 RPC
swctl trace list --service-name=order-service && swctl trace <trace-id>
# 5) UI 交叉验证:Trace → 过滤 minDuration=2000 → 瀑布图;6) 查 database_access_resp_time 是否吻合
- 验证:瀑布图中单个 Span 占总耗时 >80%;
database_access_resp_time与慢调用时段吻合。 - 回滚:仅新增
endpoint_slow_rule,删除该 rule 并重启 OAP 即回滚;⚠️ 重启 OAP 会短暂中断 :12800 查询,选非高峰执行。
7.3 接入一个 Go 服务(OTLP 路径)
- 目标:不想改 Go 构建命令时,用 OTel SDK 经 OTLP 上报。步骤:启用 OAP OTLP receiver → 应用设标准 OTel 环境变量 → 重启。
# OAP 侧(与 3.2 方式 D 一致的 Docker 环境变量)
SW_OTEL_RECEIVER=default
SW_OTEL_RECEIVER_ENABLED_OTEL_METRICS_RULES=vm
# 应用侧:OTel SDK 支持环境变量自动配置,无需 SkyWalking 专用 Agent
export OTEL_SERVICE_NAME=payment-service OTEL_EXPORTER_OTLP_ENDPOINT=http://<OAP_HOST>:11800
export OTEL_EXPORTER_OTLP_PROTOCOL=grpc OTEL_TRACES_SAMPLER=parentbased_traceidratio OTEL_TRACES_SAMPLER_ARG=0.1
./payment-service
若用原生 Go Agent(apache/skywalking-go),需按该仓库用
go build -toolexec改写构建命令,版本/用法以官方 README 为准。
- 验证:
swctl service list出现payment-service;UI 拓扑出现与order-service的调用边。 - 回滚:清空
OTEL_*并重启应用;OAP 侧SW_OTEL_RECEIVER保留不影响既有 Agent 接入。
7.4 告警推送到企业微信
- 目标/步骤:慢调用告警直达值班群 → 写
hooks.wechat(第 6 章)→ 重启 OAP → 压测触发阈值。 - 验证:群内收到
text-template渲染消息,OAP 日志无Send webhook failed。回滚:注释hooks段并重启 OAP;⚠️ 机器人 key 属敏感信息,勿提交进 Git。
8. 日常运维与故障排查
bin/startup.sh # OAP + UI bin/oapService.sh # 只起 OAP
bin/webappService.sh # 只起 UI tail -f logs/skywalking-oap-server.log
tail -f logs/webapp.log tail -f <agent目录>/logs/skywalking-api.log
curl -sS http://<OAP_HOST>:12800/healthcheck # 健康检查
curl -sS http://<OAP_HOST>:1234/metrics # OAP 自监控(SW_TELEMETRY=prometheus)
systemctl status skywalking-oap
| 现象 | 原因 | 处置 |
|---|---|---|
| UI 打开但服务列表为空 | Agent 未连上 :11800 / 服务名重复 / 采集周期未到 | telnet <OAP> 11800;查 agent 日志;等 1~2 分钟;确认填 gRPC 端口 |
| OAP 启动即退、存储连接失败 | BanyanDB/ES 未就绪或地址/版本不匹配 | 先起存储;核对 SW_STORAGE_BANYANDB_TARGETS;核对 4.4 兼容 API 版本 |
写入报 incompatible API version |
OAP 与 BanyanDB 跨大版本 | 按 bydb.yml 兼容列表换匹配 BanyanDB Server 版本 |
| 告警不触发 / Webhook 收不到 | 规则格式错 / 网络不通 / hooks 缩进错 |
按 4.5 重写 MQE;curl -v <webhook URL>;对照发行包模板 |
| 拓扑有节点但缺调用边 | 网关/MQ 吞掉 Context header | 透传 sw8/traceparent;启用对应插件 |
| 链路断裂、时间线错乱 / 升级后 UI 白屏 | 时钟漂移 / UI 与 OAP 版本不一致 | 全节点 NTP;两者用同一发行包版本 |
| OAP CPU/内存高、队列积压 | 采样过高 / Span 过大 / 存储写慢 | 调采样与 Span 上限;扩 OAP;看 :1234 队列指标 |
9. 性能、容量与高可用
| 维度 | 建议 |
|---|---|
| 探针开销 / 采样 | Java Agent 常为个位数百分比 CPU + 少量堆,随 Span 数线性增长;生产 10%~100%,核心交易高采样、边缘低采样。SkyWalking 是每 3 秒 N 段,与 OTel traceidratio 语义不同,勿混用 |
| 存储容量估算 | 日容量 ≈ 日均 Span 数 × 单 Span 落盘字节 × 副本数 × 保留天数;先用 7 天全采样实测日增磁盘,再按 service_cpm × 平均 Span/Trace × 峰值倍数 外推;ES 另算副本与索引 |
| 数据保留 / 集群 / 缓冲 | core.default.*DataTTL 分控 metrics/record;SW_CLUSTER=standalone 仅开发,生产用 kubernetes/zookeeper/nacos + LB 分摊 :11800;高流量在 Agent 与 OAP 间放 Kafka receiver / Satellite |
| 存储 HA / 自监控 / 红线 | BanyanDB 2 liaison + 2 data 起步,ES/OpenSearch ≥3 节点 + 副本;SW_TELEMETRY=prometheus → :1234/metrics 看队列深度、写延迟、GraphQL P99(OAP 11 另有 :17128 admin);写入接近上限时优先降采样而非只扩 OAP |
10. 安全加固、备份与升级
| 项 | 做法 |
|---|---|
| 认证鉴权 / TLS / 暴露面 | :12800 / :8080 默认无认证,生产置于反向代理/Ingress 后加 SSO/Basic Auth/ACL(Horizon 提供 RBAC);Agent→OAP 可用 agent.authentication(以对应版本文档为准)。对外 HTTPS 卸载,内网 :11800 可启 TLS;只对外暴露 UI :8080,其余端口仅内网可达 |
| 最小权限 / 敏感数据 | OAP/UI 非 root,DB 只授所需库表,Rover 仅必要节点开 privileged;探针可采 SQL 参数、HTTP header,按需关闭 plugin.*.trace_param 类插件,告警模板避免带出用户隐私 |
| 备份 / 版本兼容 | 明确 TTL,BanyanDB/ES 按官方方式做快照并定期演练恢复;application.yml/alarm-settings.yml/bydb.yml/Helm values 入 Git。Java Agent 与 OAP 独立发版,大版本跨度须查官方兼容矩阵(OTLP 接入无此约束) |
| 升级 / 回滚 | 备份 → 查兼容矩阵(尤其 4.4 BanyanDB API)→ 先升存储(如需) → 滚动升 OAP → 升 UI → 分批升 Agent → 验证拓扑/告警;保留上一版发行包与镜像 tag,⚠️ 存储 schema 通常不可自动降级,回滚前先做快照 |
11. 常见坑
| # | 现象 | 原因 | 解决 |
|---|---|---|---|
| 1 | ⚠️ 生产用 H2,重启数据全丢 | H2 是内存/本地演示库 | 改 BanyanDB/ES/MySQL;显式设 SW_STORAGE |
| 2 | ⚠️ 升 OAP 后写入失败、API 版本不兼容 | OAP 与 BanyanDB 跨大版本 | 按 bydb.yml 兼容 API 版本映射选 BanyanDB Server,三方一起规划升级 |
| 3 | Agent 连不上,backend_service 填了 :12800 |
12800 是 HTTP/GraphQL,Agent 走 11800 gRPC | 改 :11800;telnet 验证 |
| 4 | 告警从 8.x 升到 9.x+ 后失效 | 规则从 metrics-name/op/threshold 改为 MQE expression |
按新版自带模板重写;规则 id 以 _rule 结尾 |
| 5 | JAVA_TOOL_OPTIONS 挂探针后所有 JVM 被注入 |
该变量是全局的 | 逐应用在启动脚本写 -javaagent;回滚时清理环境变量 |
| 6 | 服务名全叫 Your_ApplicationName / 高流量下 OAP OOM |
未设唯一名 / 全量采样 + 大 Segment | 设 SW_AGENT_NAME;设采样与 Span 上限、过滤健康检查端点 |
| 8 | 链路在网关/MQ 处断开、拓扑缺边 | 跨进程 Context header 未透传 | 透传 sw8/traceparent;启用对应插件或改 OTLP |
| 9 | ⚠️ 把 :12800 / :11800 直接暴露公网 / UI 看不到新服务 | 默认无认证 / 元数据注册延迟 | 内网隔离 + 代理鉴权;等 1~2 分钟、时间范围调「最近 15 分钟」 |
12. 速查表
| 项目 | 值 / 命令 |
|---|---|
| 分类 / 授权 | 05 APM与链路追踪 / Apache License 2.0 |
| 官网 / 仓库 | https://skywalking.apache.org/ | https://github.com/apache/skywalking |
| OAP gRPC(Agent/OTLP) | :11800 |
| OAP HTTP | :12800,POST /graphql、GET /healthcheck |
| UI / BanyanDB | :8080 / :17912 gRPC、:17913 HTTP |
| OAP 自监控 / 健康检查 | :1234/metrics(SW_TELEMETRY=prometheus)/ curl http://<OAP>:12800/healthcheck |
| 主配置 | config/application.yml、config/alarm-settings.yml、config/bydb.yml |
| UI / Agent 配置 | webapp/webapp.yml(SW_OAP_ADDRESS)/ skywalking-agent/config/agent.config |
| Agent 挂载 | -javaagent:/opt/skywalking-agent/skywalking-agent.jar |
| 服务名 / OAP 地址 | SW_AGENT_NAME / SW_AGENT_COLLECTOR_BACKEND_SERVICES(或 -Dskywalking.*) |
| 采样 / 集群 | SW_AGENT_SAMPLE(agent.sample_n_per_3_secs)/ SW_CLUSTER=standalone|kubernetes|zookeeper|nacos |
| 存储选择 | SW_STORAGE=banyandb|elasticsearch|opensearch|mysql|postgresql|h2 |
| 启动 / 日志 | bin/startup.sh、bin/oapService.sh、bin/webappService.sh / logs/skywalking-oap-server.log、logs/webapp.log、agent logs/skywalking-api.log |
| CLI | swctl --base-url=http://<OAP>:12800/graphql service list |
| GraphQL 健康查询 / 告警规则 | query { version checkHealth { score details } } / config/alarm-settings.yml(id 后缀 _rule) |
| 关键指标 | service_resp_time / service_sla / service_cpm / service_percentile |
| 企业微信 hook | hooks.wechat.webhooks → https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=<key> |
| Helm | oci://docker.io/apache/skywalking-helm |
13. 选型建议与同类对比
| 维度 | SkyWalking | Jaeger | Zipkin | Pinpoint |
|---|---|---|---|---|
| 定位 | 一体化 APM(Trace+Metrics+Log+Profile+Alarm) | 专注链路追踪(v2 基于 OTel Collector) | 轻量链路追踪 | 一体化 APM(偏 Java) |
| 埋点 | 多语言无侵入 Agent + eBPF + OTLP | 推荐 OTel SDK/OTLP,无自研语言探针 | 需引 Brave/Instrumentation 库 | Java 字节码增强,无侵入 |
| 数据模型 / 存储 | 自有 + 兼容 Zipkin v1/v2、OTLP;BanyanDB/ES/OpenSearch/MySQL/PG | OTLP 原生;Memory/Badger/Cassandra/ES/OpenSearch/ClickHouse(实验)/Kafka/Remote | Zipkin v2/B3;ES/MySQL/Cassandra/内存 | 自有;HBase 为主 |
| 服务拓扑 / 指标告警 | 内置自动依赖分析 / 内置 MAL/MQE + 告警引擎 | 依赖图(内部 API/Spark 作业)/ 无内置告警,靠外围 Prometheus | 需额外组件 / 无 | 内置很强 / 内置有限 |
| 侵入性 / 运维 / 治理 | 极低 / 中高(OAP 集群)/ ASF 顶级、国产主导 | 低(OTel 标准)/ 中(单二进制)/ CNCF 毕业 | 中(改依赖)/ 低 / 老牌轻量 | 极低 / 高(HBase)/ 韩国起源 |
何时选 SkyWalking:需要 Trace/Metrics/Log/告警一体、多语言无侵入(尤其 Java 为主)、看重中文文档与国产化生态、不想自己拼 Prometheus+Alertmanager。 何时不选:已全面标准化 OTel 且只要链路(Jaeger/Tempo/Grafana 更贴合);团队小、无法维护 OAP + BanyanDB/ES 有状态集群;只要容器/主机指标;强需求闭源商业支持。 与 Jaeger 组合:应用统一用 OTel SDK 上报,OTLP 同时送 SkyWalking(APM 与告警)和 Jaeger/Tempo(纯 Trace 归档),避免双探针。
14. 参考链接
- 官网与下载:https://skywalking.apache.org/ | https://skywalking.apache.org/downloads/
- 主仓库:https://github.com/apache/skywalking
- Java Agent / CLI:https://github.com/apache/skywalking-java | https://github.com/apache/skywalking-cli
- Helm / 查询协议 / 演示栈:https://github.com/apache/skywalking-helm | https://github.com/apache/skywalking-query-protocol | https://github.com/apache/skywalking-showcase
- OAP 后端安装:https://skywalking.apache.org/docs/main/v11.0.0/en/setup/backend/backend-setup/
- 存储后端与 selector:https://skywalking.apache.org/docs/main/next/en/setup/backend/backend-storage/
- 查询协议(含废弃 V1 元数据 API 说明):https://skywalking.apache.org/docs/main/next/en/api/query-protocol-deprecated
- BanyanDB 快速上手:https://skywalking.apache.org/docs/skywalking-banyandb/next/guides/quick-start/quick-start
- Helm OAP 端口 / 官方告警规则模板:https://skywalking.apache.org/docs/skywalking-helm/next/expose/oap-endpoints | https://github.com/apache/skywalking/blob/master/dist-material/alarm-settings.yml
- Java Agent 配置项表 / OTel:https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/configurations/ | https://opentelemetry.io/