Apache SkyWalking —— 国产开源一体化 APM:无侵入探针 + OAP 分析 + 拓扑/链路/指标/告警

运维监控软件手册 05-APM与链路追踪 25.9 KB 原文

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+ 改为 MQE expression。跨大版本升级必须按新版自带 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;UI General → 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. 参考链接

Apache SkyWalking —— 国产开源一体化 APM:无侵入探针 + OAP 分析 + 拓扑/链路/指标/告警 - 知识库 - 起航社区