SkyWalking 面试题
30 道题- 分类
- 可观测性
- 子分类
- trace
- 题目数
- 30 道
1 Apache SkyWalking 的核心架构由哪些组件组成?
答案:
SkyWalking 是 Apache 基金会的 APM(应用性能监控)系统,专注于分布式系统的 Trace、Metrics 和告警。
核心组件:
| 组件 | 职责 | 说明 |
|---|---|---|
| Agent | 应用侧探针 | 自动埋点、数据采集,无侵入式接入 |
| OAP Server | 后端处理器 | 数据接收、聚合分析、告警计算 |
| Storage | 数据存储 | 支持 Elasticsearch、H2、MySQL、TiDB |
| UI | 可视化面板 | 拓扑图、Trace 查询、告警管理 |
| CLI | 命令行工具 | GraphQL API 的 CLI 封装 |
数据流:
graph TD
A["Application"] --> B["Agent<br/>SkyWalking Agent<br/>gRPC/HTTP"]
B --> C["OAP Server<br/>集群"]
C --> D["Storage<br/>ES/MySQL"]
C --> E["Alarm<br/>告警"]
D -->|"GraphQL API"| F["UI"]
Agent 注入方式:
# Java Agent(无侵入)
java -javaagent:/path/to/skywalking-agent.jar \
-Dskywalking.agent.service_name=user-service \
-Dskywalking.collector.backend_service=oap:11800 \
-jar app.jar
2 SkyWalking 的 Agent 探针工作原理是什么?如何实现无侵入式接入?
答案:
SkyWalking Agent 基于字节码增强技术,在 JVM 层面拦截关键方法调用,自动生成 Trace 数据。
Agent 工作流程:
JVM 启动
│
javaagent 参数指定 SkyWalking Agent
│
Agent 初始化
├── 解析配置 (agent.config)
├── 加载插件
├── Instrumentation (字节码增强)
└── 连接 OAP Server
│
运行时
├── 拦截框架方法 (HTTP/gRPC/DB/MQ)
├── 创建/传播 Span
├── 收集 Trace/Metrics
└── 异步发送到 OAP
支持的框架拦截:
| 类型 | 框架 |
|---|---|
| HTTP | Tomcat, Jetty, Undertow, Spring MVC |
| gRPC | gRPC 全版本 |
| RPC | Dubbo, gRPC, Motan, SOFARPC |
| MQ | Kafka, RabbitMQ, RocketMQ, Pulsar |
| DB | JDBC, MongoDB, Redis, Elasticsearch |
| Cloud | Spring Cloud Gateway, Zuul, Sentinel |
字节码增强机制:
// Agent 插件的拦截点定义(以 Tomcat 插件为例)
public class TomcatInterceptor implements InstanceMethodsAroundInterceptor {
@Override
public void beforeMethod(EnhancedInstance objInst, Method method,
Object[] allArguments, Class<?>[] argumentsTypes) {
// 请求入口:创建 EntrySpan
Span span = ContextManager.createEntrySpan(
request.getRequestURI(),
new ContextCarrier().deserialize(
request.getHeader("sw8") // SkyWalking 协议头
)
);
span.setComponent(ComponentsDefine.TOMCAT);
}
@Override
public Object afterMethod(EnhancedInstance objInst, Method method,
Object[] allArguments, Class<?>[] argumentsTypes,
Object ret) {
// 请求结束:结束 Span
ContextManager.stopSpan();
return ret;
}
}
无侵入优势:
无需修改业务代码
无需额外 SDK 依赖
支持热插拔(运行时不上报)
升级 Agent 只需替换 jar 包
3 SkyWalking 的 Trace 数据模型:Segment、Span 和 SpanRef 的关系是什么?
答案:
SkyWalking 的 Trace 模型包括 Segment、Span 和 SpanRef,用于构建完整的分布式调用链。
数据模型层次:
Trace(全局调用链)
│
├── Segment 1 (服务A: user-service)
│ ├── Span 1 (Entry: HTTP GET /api/users)
│ │ └── SpanRef → Segment 2
│ ├── Span 2 (Local: validateToken)
│ └── Span 3 (Exit: JDBC SELECT users)
│ └── SpanRef → DB 实例
│
└── Segment 2 (服务B: order-service)
├── Span 1 (Entry: gRPC createOrder)
└── Span 2 (Exit: Kafka send)
三者关系:
| 概念 | 说明 | 粒度 | 包含关系 |
|---|---|---|---|
| Trace | 一次请求的完整调用链 | 全局 | 包含多个 Segment |
| Segment | 单个服务内的 Span 集合 | 服务级 | 包含多个 Span |
| Span | 单个操作单元 | 操作级 | — |
| SpanRef | Span 间的父子/跨进程引用 | 关联 | Span 的引用 |
Segment 与 Span 的数据结构:
// Segment (服务级别)
{
"traceSegmentId": "uuid",
"serviceId": "user-service-id",
"serviceInstanceId": "instance-1",
"spans": [Span, Span, ...]
}
// Span (操作级别)
{
"spanId": 0,
"parentSpanId": -1, // -1 表示根 Span
"startTime": 1716700000000,
"endTime": 1716700000500,
"operationName": "GET /api/users",
"spanType": "Entry", // Entry / Local / Exit
"spanLayer": "Http",
"componentId": 1, // Tomcat
"isError": false,
"logs": [],
"tags": [],
"refs": [SpanRef] // 跨进程引用
}
4 SkyWalking 的三种 Span 类型(Entry、Local、Exit)有什么区别?
答案:
SkyWalking 将 Span 分为 Entry、Local 和 Exit 三类,描述 Span 在服务边界中的角色。
Span 类型对比:
| 类型 | 说明 | 位置 | 示例 | 是否跨进程 |
|---|---|---|---|---|
| Entry | 服务入口 | 服务接收端 | HTTP 请求、gRPC 请求 | 是(接收) |
| Local | 本地调用 | 服务内部 | 方法调用、业务逻辑 | 否 |
| Exit | 服务出口 | 客户端调用 | HTTP 调用、DB 查询、MQ 发送 | 是(发送) |
Span 类型的 Trace 拓扑:
Entry Span (Tomcat: HTTP GET /api/orders)
│
├── Local Span (validatePermission)
│
├── Local Span (checkCache)
│
└── Exit Span (JDBC: SELECT orders)
│
└── [远程服务 Entry Span]
Exit Span (gRPC: UserService/GetUser)
│
└── [用户服务 Entry Span]
代码示例(自定义 Span):
// Entry Span(服务入口)
Span entrySpan = ContextManager.createEntrySpan(
request.getRequestURI(),
carrier // 跨进程传播上下文
);
entrySpan.setComponent(ComponentsDefine.TOMCAT);
// Local Span(本地操作)
Span localSpan = ContextManager.createLocalSpan(
"validatePermission"
);
localSpan.setTag("role", "admin");
// Exit Span(远程调用)
Span exitSpan = ContextManager.createExitSpan(
"/UserService/GetUser",
carrier,
"user-service:8080"
);
exitSpan.setComponent(ComponentsDefine.GRPC);
5 SkyWalking 的 OAP Server 核心功能是什么?Cluster 模式如何工作?
答案:
OAP(Observability Analysis Platform)Server 是 SkyWalking 的后端核心,负责数据接收、聚合分析和告警。
OAP 核心功能:
| 功能 | 说明 | 组件 |
|---|---|---|
| Telemetry Receiver | 接收 Agent 数据 | gRPC/HTTP Receiver |
| Trace Analyzer | Trace 数据分析 | 注册到 Streaming Processor |
| Metrics Aggregator | 指标聚合计算 | 分钟级/小时级聚合 |
| Alarm | 告警规则引擎 | Alarm Center |
| Topology | 服务拓扑分析 | Service Relation Calculator |
| Sampling | 采样策略 | 可配置采样率 |
| Storage | 数据持久化 | DAO 层(ES/MySQL/TiDB) |
Cluster 模式:
graph TD
LB[Nginx/LB] --> OAP1[OAP-1]
LB --> OAP2[OAP-2]
LB --> OAP3[OAP-3]
OAP1 --> CC[Cluster Coordinator - Nacos/ZK/K8s]
OAP2 --> CC
OAP3 --> CC
Cluster 配置:
# application.yml
cluster:
selector: ${SW_CLUSTER:zookeeper}
# Nacos Cluster
nacos:
serviceName: ${SW_CLUSTER_NACOS_SERVICE_NAME:SkyWalking_OAP_Cluster}
hostPort: ${SW_CLUSTER_NACOS_HOST_PORT:localhost:8848}
# Kubernetes Cluster
kubernetes:
watchTimeoutSeconds: ${SW_CLUSTER_K8S_WATCH_TIMEOUT:60}
namespace: ${SW_CLUSTER_K8S_NAMESPACE:default}
labelSelector: ${SW_CLUSTER_K8S_LABEL:app=oap}
uidEnvName: ${SW_CLUSTER_K8S_UID:SKYWALKING_COLLECTOR_UID}
6 SkyWalking 的存储选型:Elasticsearch、MySQL、TiDB 的对比是什么?
答案:
SkyWalking 支持多种存储后端,不同存储方案影响查询性能、存储成本和运维复杂度。
存储方案对比:
| 维度 | Elasticsearch | MySQL / PostgreSQL | TiDB | BanyanDB |
|---|---|---|---|---|
| 定位 | 通用搜索引擎 | 关系型数据库 | 分布式数据库 | 时序数据库 |
| 查询性能 | 极高 | 中 | 高 | 极高 |
| 写入性能 | 高 | 中 | 高 | 极高 |
| 存储成本 | 高 | 低 | 中 | 低 |
| 运维复杂度 | 高 | 低 | 中 | 中 |
| 集群模式 | 原生 | 需 Proxy | 原生 | 原生 |
| Day-2 运维 | 高 | 低 | 中 | 中 |
| 推荐场景 | 大规模 | 中小规模 | 大规模 | 原生 |
配置示例:
# ES 存储
storage:
selector: ${SW_STORAGE:elasticsearch}
elasticsearch:
clusterNodes: ${SW_STORAGE_ES_CLUSTER_NODES:localhost:9200}
indexShardsNumber: ${SW_STORAGE_ES_INDEX_SHARDS_NUMBER:2}
indexReplicasNumber: ${SW_STORAGE_ES_INDEX_REPLICAS_NUMBER:0}
bulkActions: ${SW_STORAGE_ES_BULK_ACTIONS:1000}
bulkSize: ${SW_STORAGE_ES_BULK_SIZE:20}
flushInterval: ${SW_STORAGE_ES_FLUSH_INTERVAL:10}
concurrentRequests: ${SW_STORAGE_ES_CONCURRENT_REQUESTS:2}
advanced: ${SW_STORAGE_ES_ADVANCED:""}
# MySQL 存储
storage:
selector: ${SW_STORAGE:mysql}
mysql:
properties:
jdbcUrl: ${SW_JDBC_URL:"jdbc:mysql://localhost:3306/swtest"}
dataSource.user: ${SW_DATA_SOURCE_USER:root}
dataSource.password: ${SW_DATA_SOURCE_PASSWORD:root}
metadataQueryMaxSize: ${SW_STORAGE_MYSQL_QUERY_MAX_SIZE:5000}
# TiDB 存储
storage:
selector: ${SW_STORAGE:tidb}
tidb:
properties:
jdbcUrl: ${SW_JDBC_URL:"jdbc:mysql://tidb-server:4000/skywalking"}
dataSource.user: ${SW_DATA_SOURCE_USER:root}
maxSizeOfArrayColumn: ${SW_STORAGE_MAX_SIZE_OF_ARRAY_COLUMN:500}
选型建议:
| 日均 Trace 量 | 推荐存储 | 节点数 |
|---|---|---|
| < 1 亿 | MySQL / PostgreSQL | 1-3 |
| 1-10 亿 | Elasticsearch | 3-9 |
| 10-100 亿 | TiDB / BanyanDB | 3-15 |
| > 100 亿 | BanyanDB | 5+ |
7 SkyWalking 的告警机制如何配置?告警规则支持哪些条件?
答案:
SkyWalking 内置告警引擎,基于 OAP 聚合的指标数据实现条件匹配和通知分发。
告警规则配置:
# alarm-settings.yml
rules:
# 规则名称
service_resp_time_rule:
# 指标名称
metrics-name: service_resp_time
# 阈值
threshold: 1000
# 操作符:> / < / =
op: ">"
# 评估周期(分钟)
period: 10
# 持续次数
count: 3
# 静默时间(分钟)
silence-period: 5
# 消息模板
message: |
Service {name} response time {value} exceeds 1000ms in last 10 minutes.
service_sla_rule:
metrics-name: service_sla
threshold: 80
op: "<"
period: 10
count: 3
message: |
Service {name} SLA {value} is lower than 80% in last 10 minutes.
# 端点延迟告警
endpoint_resp_time_rule:
metrics-name: endpoint_resp_time
threshold: 2000
op: ">"
period: 10
count: 5
message: |
Endpoint {name} response time {value} exceeds 2000ms.
# 异常率告警
endpoint_sla_rule:
metrics-name: endpoint_sla
threshold: 90
op: "<"
period: 10
count: 3
message: |
Endpoint {name} SLA {value} is lower than 90%.
告警通知配置:
# 通知方式
hooks:
# Webhook
webhook:
default:
is-default: true
urls:
- http://alertmanager:9093/api/v1/alerts
- http://webhook-service:8080/skywalking-alert
# 钉钉
dingtalk:
text-template: |
SkyWalking Alarm:
- Rule: {ruleName}
- Service: {scopeName}
- Message: {message}
- Time: {date}
webhooks:
- url: https://oapi.dingtalk.com/robot/send?access_token=xxx
secret: your-secret
# 企业微信
wechat:
webhooks:
- url: https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx
# Slack
slack:
text-template: |
*SkyWalking Alarm*
*Rule:* {ruleName}
*Service:* {scopeName}
*Message:* {message}
webhooks:
- url: https://hooks.slack.com/services/xxx
8 SkyWalking 的服务拓扑图是如何生成的?服务依赖关系如何自动发现?
答案:
SkyWalking 通过分析 Span 中的跨进程引用自动构建服务拓扑图,无需手动配置服务依赖。
拓扑生成原理:
Agent 拦截每次远程调用
│
Entry Span 记录服务A
Exit Span 记录服务B
│
SpanRef (跨进程引用)
│
OAP Server 聚合
│
服务依赖关系:
ServiceA → ServiceB: 1000次/分钟, P50=50ms, 错误率=1%
SpanRef 结构:
// Exit Span 生成的引用
SpanRef ref = new SpanRef();
ref.setParentService("user-service");
ref.setParentInstance("user-service-1");
ref.setParentEndpoint("GET /api/users");
ref.setTargetService("order-service");
ref.setTargetEndpoint("gRPC /OrderService/Create");
ref.setRefType(RefType.CrossProcess);
拓扑数据结构:
{
"nodes": [
{
"id": "user-service",
"name": "user-service",
"type": "SERVICE",
"isReal": true,
"metrics": {
"avgResponseTime": 150,
"cpm": 1000, // 每分钟请求数
"apdex": 0.95, // 应用性能指数
"sla": 99.5 // 服务等级协议
}
}
],
"calls": [
{
"source": "user-service",
"target": "order-service",
"metrics": {
"avgResponseTime": 50,
"cpm": 800,
"sla": 99.8
}
}
]
}
可视化拓扑图功能:
拓扑图展示:
- 服务节点(圆角矩形)
- 依赖连线(箭头指向)
- 节点颜色表示健康状态(绿/黄/红)
- 连线上显示调用量和延迟
- 点击节点查看详情
- 拖动布局
故障场景拓扑:
服务变红 → 箭头变红 → 调用方 SLA 下降
→ 快速定位故障影响范围
9 SkyWalking 支持哪些语言的 Agent?语言兼容性如何?
答案:
SkyWalking 提供多语言 Agent 实现,Java Agent 最为成熟完善,其他语言持续跟进中。
语言支持矩阵:
| 语言 | Agent 状态 | 维护者 | 自动埋点能力 |
|---|---|---|---|
| Java | GA(生产可用) | 官方 | 强(字节码增强) |
| Go | GA | 官方 | 中(手动+自动) |
| Node.js | GA | 官方 | 中 |
| Python | GA | 社区 | 中 |
| Lua | Beta | 社区 | Nginx/OpenResty |
| .NET | Beta | 社区 | 中 |
| PHP | Alpha | 社区 | 基础 |
| C++ | Alpha | 社区 | 基础 |
| Rust | Alpha | 社区 | 基础 |
Java Agent(最成熟):
# 完整的 Java Agent 支持
# 框架:Spring Boot, Dubbo, Tomcat, gRPC, Kafka, JDBC, Redis, RocketMQ
# 功能:自动 Trace、自动 Metrics、自动告警
java -javaagent:/skywalking-agent/skywalking-agent.jar \
-Dskywalking.agent.service_name=user-service \
-Dskywalking.collector.backend_service=oap:11800 \
-jar app.jar
Go Agent:
import (
"github.com/apache/skywalking-go"
)
func main() {
// 自动配置(通过环境变量)
// SW_AGENT_NAME=user-service
// SW_AGENT_COLLECTOR_BACKEND_SERVICES=oap:11800
// 手动创建 Span
tracer, _ := skywalking.NewTracer("user-service")
span := tracer.StartSpan("/api/users")
defer span.End()
// 自动埋点(HTTP 框架自动拦截)
http.HandleFunc("/api/users", handler)
}
10 SkyWalking 的 gRPC 和 HTTP 协议在数据传输中的区别?
答案:
SkyWalking 支持 gRPC 和 HTTP(JSON)两种传输协议,gRPC 作为默认高性能通信方式。
协议对比:
| 维度 | gRPC | HTTP |
|---|---|---|
| 传输层 | HTTP/2 | HTTP/1.1 |
| 编码 | Protobuf | JSON |
| 性能 | 高(二进制、流式) | 中 |
| Agent 默认 | 是 | 备选 |
| Browser 支持 | 有限 | 原生 |
| 跨语言 | Protobuf IDL | 通用 JSON |
| 推荐场景 | Agent → OAP | 第三方系统集成 |
Agent 端配置:
# agent/config/agent.config
# gRPC(默认,推荐)
collector.backend_service=${SW_AGENT_COLLECTOR_BACKEND_SERVICES:oap:11800}
# HTTP(备选)
# collector.backend_service=${SW_AGENT_COLLECTOR_BACKEND_SERVICES:oap:12800}
OAP 监听配置:
# application.yml
core:
gRPCHost: ${SW_GRPC_HOST:0.0.0.0}
gRPCPort: ${SW_GRPC_PORT:11800}
receiver-sharing:
selector: ${SW_RECEIVER_SHARING:default}
default:
restHost: ${SW_REST_HOST:0.0.0.0}
restPort: ${SW_REST_PORT:12800}
restContextPath: ${SW_REST_CONTEXT_PATH:/}
11 SkyWalking 与 OpenTelemetry 的关系和集成方式是什么?
答案:
SkyWalking 支持接收 OTel 数据,通过 OTel Receiver 或 SkyWalking OTLP Exporter 实现集成。
集成架构:
方式一:OTel Collector → SkyWalking OAP
App → OTel SDK → OTel Collector → OAP (gRPC)
│
Analysis & Storage
方式二:OTel SDK → SkyWalking OAP(直接)
App → OTel SDK (SkyWalking Exporter) → OAP
方式三:SkyWalking Agent → OTel Collector
App → SW Agent → OTelemetryOAP → OTel Collector → Any Backend
OTel Collector 配置(发送到 SkyWalking):
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
processors:
batch:
timeout: 1s
send_batch_size: 1024
exporters:
skywalking:
endpoint: skywalking-oap:11800
num_grpc_workers: 4
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [skywalking]
关系定位:
| 维度 | SkyWalking | OpenTelemetry |
|---|---|---|
| 定位 | APM 平台(完整方案) | 遥测标准(API/SDK) |
| 组件范围 | Agent + OAP + UI + 告警 | API + SDK + Collector |
| 可视化 | 内置 UI | 依赖 Grafana 等 |
| 告警 | 内置告警引擎 | 需外部告警系统 |
| Trace 协议 | 自有协议 + OTLP | OTLP |
| 互操作性 | 支持 OTel 数据输入 | 可通过 Exporter 输出到 SW |
集成场景:
多语言环境:Java 用 SW Agent,其他语言用 OTel SDK
→ OTel Collector 统一转发到 SkyWalking
已有 OTel 基础设施:
→ OTel Collector added SW Exporter → 同时发送到 SW 和 Jaeger
12 SkyWalking 的 Metrics 指标体系包括哪些?Service、Instance、Endpoint 指标?
答案:
SkyWalking 在 Service、Instance 和 Endpoint 三个层次定义指标体系,每个层次包含延迟、吞吐量和成功率。
三级指标体系:
| 层次 | 粒度 | 代表指标 | 说明 |
|---|---|---|---|
| Service | 服务级 | service_resp_time / service_cpm / service_sla | 整体健康 |
| Instance | 实例级 | instance_jvm_cpu / instance_jvm_memory / instance_cpm | 单实例监控 |
| Endpoint | 接口级 | endpoint_resp_time / endpoint_cpm / endpoint_sla | API 级别 |
Service 指标:
service_resp_time : 服务平均响应时间 (ms)
service_cpm : 每分钟调用次数
service_sla : 服务成功率 (%)
service_apdex : 应用性能指数 (0-1)
Instance 指标(含 JVM):
instance_jvm_cpu : CPU 使用率 (%)
instance_jvm_memory_heap : 堆内存 (bytes)
instance_jvm_memory_noheap : 非堆内存 (bytes)
instance_jvm_gc_time : GC 耗时 (ms)
instance_jvm_gc_count : GC 次数
instance_jvm_thread_count : 线程数
instance_jvm_thread_blocked : 阻塞线程数
Endpoint 指标:
endpoint_resp_time : 端点平均响应时间 (ms)
endpoint_cpm : 端点每分钟调用次数
endpoint_sla : 端点成功率 (%)
endpoint_avg : 平均延迟 (ms)
endpoint_p50/p90/p95/p99 : 百分位延迟
Prometheus 兼容:
# SkyWalking OAP 暴露 Prometheus 格式指标
telemetry:
selector: ${SW_TELEMETRY:prometheus}
prometheus:
host: ${SW_TELEMETRY_PROMETHEUS_HOST:0.0.0.0}
port: ${SW_TELEMETRY_PROMETHEUS_PORT:1234}
sslEnabled: ${SW_TELEMETRY_PROMETHEUS_SSL_ENABLED:false}
13 SkyWalking 的数据库慢查询监控如何实现?
答案:
SkyWalking Agent 自动拦截 JDBC 调用,记录 SQL 语句和执行耗时,支持慢查询告警。
JDBC 拦截原理:
应用 → JDBC Driver → SkyWalking 插件
│
拦截 PreparedStatement.execute()
│
创建 Exit Span (DB 类型)
│
记录 SQL 语句、参数
│
计算执行耗时
│
标记慢查询(配置阈值)
│
发送到 OAP Server
慢查询配置:
# agent.config
# 慢查询阈值(默认 200ms)
plugin.mysql.trace_sql_parameters=true
plugin.mysql.sql_parameters_max_length=256
# PostgreSQL
plugin.postgresql.trace_sql_parameters=true
Slow SQL 数据:
{
"traceId": "abc123",
"statement": "SELECT * FROM users WHERE status = ? AND created_at > ?",
"parameters": ["active", "2026-01-01"],
"latency": 3500,
"startTime": "2026-05-26T10:00:00Z",
"service": "user-service",
"instance": "user-service-1",
"database": "postgresql://db-host:5432/users",
"connection": "100"
}
慢查询查询(UI / API):
SkyWalking UI → Database → Slow SQL
显示:SQL 语句、执行次数、平均延迟、最大延迟
排序:按延迟降序
过滤:按数据库类型、服务名
GraphQL API:
query slowSQLs {
slowSQLs(condition: {
metricName: "database_slow_sql"
serviceId: "user-service"
}) {
statement
latency
count
}
}
14 SkyWalking 的跨进程传播协议(Sw8)是如何工作的?
答案:
Sw8 是 SkyWalking 的跨进程 Context 传播协议,通过 HTTP Header / gRPC Metadata 传递 Trace 上下文。
Sw8 Header 格式:
sw8: 1-{traceId}-{segmentId}-{spanId}-{service}-{instance}-{endpoint}-{targetAddress}-{correlation}
字段说明:
| 位置 | 字段 | 说明 | 示例 |
|---|---|---|---|
| 1 | Version | 协议版本 | 1 |
| 2 | Trace ID | 全局 Trace ID | abc123... |
| 3 | Segment ID | 上游 Segment ID | seg-xyz... |
| 4 | Span ID | 上游 Span ID | 1 |
| 5 | Service | 上游服务名 | user-service |
| 6 | Instance | 上游实例 | user-1 |
| 7 | Endpoint | 上游端点 | GET /api/users |
| 8 | Target Address | 目标地址 | 10.0.1.5:8080 |
| 9 | Correlation | 关联数据 | Base64 编码 |
传播流程:
服务A (user-service)
创建 Exit Span → 设置 sw8 Header
HTTP 请求 → sw8: 1-abc123-segA-0-user-service-user-1-GET%2Fapi%2Fusers-10.0.1.5:8080-
服务B (order-service)
HTTP 接收 → 解析 sw8 Header
创建 Entry Span → 继承上下文
创建新的 Segment
Kafka MQ 传播:
// Kafka 消息的 Context 传播通过消息 Header
ProducerRecord<String, String> record = new ProducerRecord<>("orders", message);
// SkyWalking 自动注入到 record.headers()
// headers: ["sw8": "1-abc123-segA-0-user-service-user-1-sendOrder-..."]
与其他协议的兼容:
| 协议 | Header | 说明 |
|---|---|---|
| Sw8 | sw8 | SkyWalking 原生 |
| Sw8-x | sw8-x | 扩展协议 |
| W3C TraceContext | traceparent | OTel 兼容 |
| B3 | b3 / x-b3-* | Zipkin 兼容 |
15 SkyWalking 的采样策略和 Trace 数据存储策略是什么?
答案:
SkyWalking 支持 Agent 端采样和 OAP 端采样,通过配置采样率控制数据量。
Agent 端采样:
# agent/config/agent.config
# 基于 Trace 的采样率(默认 100%)
agent.sample_n_per_3_secs=${SW_AGENT_SAMPLE_N_PER_3_SECS:-1}
# -1: 全部采样
# 正整数: 每 3 秒采样 N 条 Trace
# 忽略指定端点
agent.ignore_suffix=${SW_AGENT_IGNORE_SUFFIX:.jpg,.jpeg,.js,.css,.png,.bmp,.ico,.gif}
# 忽略指定路径
agent.operation_name_threshold: ${SW_AGENT_OPERATION_NAME_THRESHOLD:150}
OAP 端采样:
# application.yml
core:
# Trace 采样率(0-10000,精确到万分比)
sampleRate: ${SW_CORE_SAMPLE_RATE:10000}
# 慢查询采样率
slowTraceThreshold: ${SW_SLOW_TRACE_THRESHOLD:-1}
存储策略:
| 数据 | 保留期 | 清理机制 | 说明 |
|---|---|---|---|
| Segment/Trace | 3-7 天 | TTL 自动清理 | Trace 原始数据 |
| 分钟级指标 | 7 天 | TTL | 每分钟聚合 |
| 小时级指标 | 30 天 | TTL | 每小时聚合 |
| 天级指标 | 90 天 | TTL | 每天聚合 |
| 日志 | 7 天 | TTL | 关联日志 |
| 告警历史 | 30 天 | TTL | 告警事件 |
TTL 配置:
# ES 存储 TTL 配置
storage:
elasticsearch:
# Trace 数据
recordDataTTL: ${SW_STORAGE_ES_RECORD_DATA_TTL:7}
# 分钟级指标
minuteMetricsDataTTL: ${SW_STORAGE_ES_MINUTE_METRICS_DATA_TTL:7}
# 小时级指标
hourMetricsDataTTL: ${SW_STORAGE_ES_HOUR_METRICS_DATA_TTL:30}
# 天级指标
dayMetricsDataTTL: ${SW_STORAGE_ES_DAY_METRICS_DATA_TTL:90}
# 月份级指标
monthMetricsDataTTL: ${SW_STORAGE_ES_MONTH_METRICS_DATA_TTL:18}
16 SkyWalking UI 的核心功能和数据展示方式是什么?
答案:
SkyWalking UI 提供多维度的可观测性数据展示,包括仪表盘、拓扑图、Trace 查询和告警管理。
UI 核心模块:
| 模块 | 功能 | 使用场景 |
|---|---|---|
| Dashboard | 全局指标总览 | 团队每日巡检 |
| Topology | 服务拓扑图 | 调用关系可视化 |
| Trace | Trace 查询和详情 | 慢请求/错误排查 |
| Profile | 代码级性能分析 | 方法耗时分析 |
| Log | 关联日志查询 | 日志上下文查看 |
| Alarm | 告警管理和通知 | 异常通知和响应 |
| Database | 数据库调用分析 | 慢 SQL 查询 |
| Configuration | 告警规则和 UI 配置 | 平台配置管理 |
Dashboard 面板类型:
Services Dashboard:
- 全局响应时间趋势
- 全局吞吐量趋势
- 全局 SLA 趋势
- 慢端点 Top 10
- 错误端点 Top 10
- 服务列表(SLA 排序)
Instance Dashboard:
- JVM CPU 使用率
- JVM 堆/非堆内存
- GC 频率和耗时
- 实例级吞吐量
- 实例级延迟
Endpoint Dashboard:
- 端点延迟 (P50/P90/P95/P99)
- 端点吞吐量
- 端点 SLA
- 慢端点详情
Trace 查询界面:
查询条件:
- 服务名 / 端点名
- 时间范围
- Trace ID (精确查询)
- 最小/最大耗时
- 是否错误
- Tags 过滤
列表视图:
Trace ID / 端点 / 耗时 / 状态 / 时间
✓ 按耗时降序(慢请求优先)
详情视图:
甘特图展示 Span 时间线
每个 Span 包含 Tags / Logs / 关联
✓ Span 展开查看属性
✓ 跨服务跳转
17 SkyWalking 的日志集成和 Logback/Log4j 关联配置是什么?
答案:
SkyWalking 支持将 Trace ID 注入到应用日志中,实现在 UI 中从 Trace 跳转到日志,或从日志关联到 Trace。
日志关联原理:
SkyWalking Agent
│
注入 Trace ID 到 MDC
│
Logback/Log4j 配置 %X{tid}
│
日志输出含 traceId
│
在 UI 中可点击跳转
Logback 配置:
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<!-- %tid 由 SkyWalking Agent 自动替换为 Trace ID -->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} [%tid] - %msg%n</pattern>
</encoder>
</appender>
<!-- SkyWalking gRPC Log Reporter -->
<appender name="GRPC" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} [%tid] - %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="GRPC"/>
</root>
</configuration>
Log4j2 配置:
<Configuration>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} [%X{tid}] - %msg%n"/>
</Console>
<GRPCLogClientAppender name="GRPC">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} [%X{tid}] - %msg%n"/>
</GRPCLogClientAppender>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Console"/>
<AppenderRef ref="GRPC"/>
</Root>
</Loggers>
</Configuration>
Maven 依赖:
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-logback-1.x</artifactId>
<version>${skywalking.version}</version>
</dependency>
18 SkyWalking 的 Profile(代码级性能分析)功能是如何工作的?
答案:
SkyWalking Profile 功能通过采样线程堆栈实现方法级性能分析,定位热点方法和瓶颈。
Profile 工作原理:
1. 选择目标端点 → 发起 Profile 任务
2. Agent 按配置频率采样线程堆栈
3. 堆栈数据 → OAP 聚合分析
4. UI 展示火焰图 / 调用树
5. 定位热点方法
Profile 配置:
# agent/config/agent.config
# 最大采样线程数
plugin.threading.max_sampling_count: ${SW_PLUGIN_THREADING_MAX_SAMPLING_COUNT:20}
# Profile 线程池大小
plugin.threading.thread_pool_size: ${SW_PLUGIN_THREADING_THREAD_POOL_SIZE:4}
# 采样持续时间(分钟)
plugin.threading.duration_based_sampling: ${SW_PLUGIN_THREADING_DURATION_BASED_SAMPLING:true}
Profile 任务参数(UI 触发):
参数说明:
- 端点: 要分析的 API
- 监控时长: 1-10 分钟
- 采样间隔: 10-100ms
- 最大采样数: 100-10000
监控过程中:
Agent 按间隔采集线程堆栈
堆栈 trace → OAP 分析
→ 生成调用树和火焰图
火焰图解读:
火焰图(Flame Graph):
X 轴: 代码调用栈宽度(越宽 = 调用次数越多)
Y 轴: 调用深度(越深 = 调用链越长)
颜色: 无特殊含义(随机分配)
调用树(Call Tree):
Root 方法
├── 子方法 1 (耗时 50% / 调用 100 次)
├── 子方法 2 (耗时 30% / 调用 50 次)
│ ├── 子方法 2.1 (耗时 20%)
│ └── 子方法 2.2 (耗时 10%)
└── 子方法 3 (耗时 20%)
19 SkyWalking 的 Service Mesh 集成(Istio)是如何工作的?
答案:
SkyWalking 通过 Mixer 适配器或 Istio 的 Telemetry API 获取 Service Mesh 数据,实现非侵入式的服务拓扑。
数据来源架构:
graph TD
Envoy[Istio Sidecar - Envoy] --> W1[方式一: Istio Telemetry API v2]
W1 --> Wasm[Wasm Plugin]
Wasm --> SW[SkyWalking]
Envoy --> W2[方式二: Envoy Access Log + Metadata]
W2 --> SW2[SkyWalking]
SkyWalking Istio 集成配置:
# OAP 配置启用 Istio 数据接收
receiver-envoy:
selector: ${SW_RECEIVER_ENVOY:default}
default:
acceptMetricsService: ${SW_RECEIVER_ENVOY_ACCEPT_METRICS_SERVICE:true}
acceptTracingService: ${SW_RECEIVER_ENVOY_ACCEPT_TRACING_INFORMATION:true}
# ALS (Access Log Service) 配置
envoy-metrics:
alsHTTPAnalysis: ${SW_ENVOY_METRICS_ALS_HTTP_ANALYSIS:""}
Istio Telemetry API 配置:
apiVersion: telemetry.istio.io/v1alpha1
kind: Telemetry
metadata:
name: skywalking
namespace: istio-system
spec:
accessLogging:
- providers:
- name: skywalking
tracing:
- providers:
- name: skywalking
apiVersion: extensions.istio.io/v1alpha1
kind: WasmPlugin
metadata:
name: skywalking
namespace: istio-system
spec:
selector:
matchLabels:
istio: sidecar-injector
url: oci://skywalking-wasm/skywalking-envoy:latest
phase: STATS
priority: 100
Mesh 拓扑 vs 应用拓扑:
应用拓扑(Agent 采集):
- 在应用代码层面构建
- 包含应用框架信息
- 适用于有 Agent 部署的服务
Mesh 拓扑(Istio 采集):
- 在网络层面构建
- 无需 Agent,容器化即可
- 适用于所有 Sidecar 服务
两者可同时使用,互相补充
20 SkyWalking 的告警引擎指标类型和 Prometheus 告警规则的互操作性?
答案:
SkyWalking 内置告警指标与 Prometheus 告警规则可互相转换,支持告警信息互通。
内置告警指标类型:
# SkyWalking 告警规则支持的指标前缀
# service_* : 服务级别指标
# endpoint_* : 端点级别指标
# instance_* : 实例级别指标
# database_* : 数据库调用指标
rules:
service_resp_time_rule:
metrics-name: service_resp_time
threshold: 1000
op: ">"
period: 10
count: 3
service_sla_rule:
metrics-name: service_sla
threshold: 80
op: "<"
period: 10
count: 3
Prometheus 告警转换:
# Prometheus 等效告警规则
groups:
- name: skywalking-equivalent
rules:
- alert: ServiceResponseTimeHigh
expr: skywalking_service_resp_time > 1000
for: 10m
annotations:
summary: "Service XQOPEN $labels.service XQCLOSE response time > 1000ms"
- alert: ServiceSLALow
expr: skywalking_service_sla < 80
for: 10m
annotations:
summary: "Service XQOPEN $labels.service XQCLOSE SLA < 80%"
告警转发:
# SkyWalking 告警 → Prometheus AlertManager
hooks:
webhook:
default:
urls:
- http://alertmanager:9093/api/v1/alerts
- http://webhook-service:8080/skywalking-alert
# Prometheus 告警 → SkyWalking(通过 API)
# SkyWalking 提供 API 输入外部告警
21 SkyWalking 的 Database Slow SQL 和 Database Topology 的功能是什么?
答案:
Database 模块专门分析数据库调用,提供慢 SQL 查询和数据库依赖拓扑。
Database 调用分析:
graph TD
S["Service"] --> E["Exit Span<br/>数据库类型"]
E --> OA["OAP 聚合"]
OA --> SS["Slow SQL<br/>慢查询TOP N"]
OA --> DT["DB Topology<br/>数据库依赖拓扑"]
OA --> DM["Database Metrics<br/>延迟/吞吐量"]
Slow SQL 功能:
UI → Database → Slow SQL
展示:
- SQL 语句(含参数)
- 数据库类型(MySQL/PostgreSQL/Redis/MongoDB)
- 执行次数
- 平均延迟 / 最大延迟
- 所属服务 / 实例
- 最近执行时间
排序:按平均延迟 / 最大延迟 / 执行次数
过滤:按数据库类型 / 服务名 / 时间范围
Database Topology:
拓扑图展示服务与数据库的依赖关系:
user-service → PostgreSQL (users)
user-service → Redis (cache)
order-service → MySQL (orders)
order-service → Elasticsearch (search)
连线信息:
- 调用量 (cpm)
- 平均延迟 (ms)
- SLA (%)
节点颜色:健康状态
- 绿: SLA >= 99%
- 黄: SLA 90-99%
- 红: SLA < 90%
22 SkyWalking 的报警通知方式有哪些?如何配置企业微信/钉钉/Slack?
答案:
SkyWalking 支持多种报警通知渠道,通过 webhook 或直接集成 IM 机器人。
通知方式:
| 方式 | 配置 | 适用场景 |
|---|---|---|
| Webhook | 任意 HTTP 接口 | 自建告警系统 |
| 钉钉 | 机器人 Webhook | 国内 IM |
| 企业微信 | 机器人 Webhook | 国内 IM |
| Slack | Webhook URL | 海外 IM |
| 飞书 | 机器人 Webhook | 国内 IM |
| PagerDuty | Events API | On-Call |
钉钉配置:
hooks:
dingtalk:
text-template: |
SkyWalking 告警通知
告警规则: {ruleName}
服务名称: {scopeName}
告警内容: {message}
触发时间: {date}
dingtalk:
webhooks:
- url: https://oapi.dingtalk.com/robot/send?access_token=xxx
secret: your-secret
企业微信配置:
hooks:
wechat:
text-template: |
SkyWalking 监控告警
================
规则: {ruleName}
服务: {scopeName}
详情: {message}
时间: {date}
webhooks:
- url: https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx
Slack 配置:
hooks:
slack:
text-template: |
*SkyWalking Alarm*
*Rule:* {ruleName}
*Service:* {scopeName}
*Message:* {message}
*Time:* {date}
webhooks:
- url: https://hooks.slack.com/services/T0/B0/xxx
模板变量:
| 变量 | 说明 | 示例 |
|---|---|---|
{ruleName} | 告警规则名称 | service_resp_time_rule |
{scopeName} | 作用域名称 | user-service |
{scopeId} | 作用域 ID | 1 |
{id0} | 第一级 ID | user-service |
{id1} | 第二级 ID | /api/users |
{message} | 告警消息 | 自定义消息模板 |
{date} | 触发时间 | 2026-05-26 10:00:00 |
23 SkyWalking 的 K8s 部署方式(Helm Chart)与配置要点?
答案:
SkyWalking 官方提供 Helm Chart,支持一键部署 OAP Server、UI 和存储后端。
Helm 部署:
# 添加 Helm 仓库
helm repo add skywalking https://apache.github.io/skywalking-helm
helm repo update
# 部署 SkyWalking(使用 ES 存储)
helm upgrade --install skywalking skywalking/skywalking \
--namespace skywalking \
--create-namespace \
--set oap.replicas=2 \
--set oap.storageType=elasticsearch \
--set elasticsearch.enabled=true \
--values values.yaml
values.yaml 配置:
# OAP 配置
oap:
name: skywalking-oap
replicas: 2
image:
repository: apache/skywalking-oap-server
tag: 9.7.0
storageType: elasticsearch
resources:
requests:
memory: 2Gi
cpu: "1"
limits:
memory: 4Gi
cpu: "2"
env:
SW_CORE_GRPC_PORT: 11800
SW_CORE_REST_PORT: 12800
SW_HEALTH_CHECKER: "true"
SW_TELEMETRY: prometheus
SW_TELEMETRY_PROMETHEUS_PORT: 1234
# UI 配置
ui:
name: skywalking-ui
image:
repository: apache/skywalking-ui
tag: 9.7.0
replicas: 2
ingress:
enabled: true
host: skywalking.example.com
env:
SW_OAP_ADDRESS: http://skywalking-oap:12800
# ES 存储
elasticsearch:
enabled: true
replicas: 3
resources:
requests:
memory: 4Gi
persistence:
size: 200Gi
# Java Agent 配置
javaAgent:
enabled: true
config:
agent.service_name: ${SW_AGENT_NAME:default}
collector.backend_service: skywalking-oap:11800
配置要点:
OAP:
- 至少 2 副本(HA)
- storageType 选择(ES/MySQL/TiDB)
- gRPC 端口 11800(Agent 连接)
- REST 端口 12800(UI 连接)
UI:
- SW_OAP_ADDRESS 指向 OAP REST 端口
- Ingress 配置对外暴露
Agent 注入:
- 通过 Init Container 或 Sidecar 注入
- 配置 collector.backend_service
24 SkyWalking 的性能消耗和资源评估方法是什么?
答案:
SkyWalking Agent 和 OAP Server 的资源消耗需要根据 Trace 吞吐量评估。
Agent 资源消耗(Java Agent):
| 指标 | 通常范围 | 影响因素 |
|---|---|---|
| CPU 增加 | 3-8% | Span 数量 / 采样率 |
| 内存(Heap) | 50-200MB | 缓冲队列大小 |
| 网络带宽 | 1-5 MB/s | Trace 吞吐量 |
| 应用延迟影响 | < 5% | Span 创建开销 |
| GC 影响 | 略有增加 | 缓冲对象创建 |
Agent 内存配置:
# agent/config/agent.config
# 缓冲队列大小
agent.span_limit_per_segment: ${SW_AGENT_SPAN_LIMIT:300}
agent.span_limit_per_segment_stack_depth: ${SW_AGENT_SPAN_LIMIT_PER_SEGMENT_STACK:200}
# 忽略指定端点减少采样
agent.ignore_suffix=${SW_AGENT_IGNORE_SUFFIX:.jpg,.jpeg,.js,.css,.png,.bmp,.ico,.gif}
OAP 资源评估:
| Trace 吞吐量 | 节点数 | 每节点 | 存储 |
|---|---|---|---|
| 1k Spans/s | 1 | 4C/8G | ES 20GB/d |
| 10k Spans/s | 2 | 8C/16G | ES 200GB/d |
| 100k Spans/s | 4 | 16C/32G | ES 2TB/d |
| 1M Spans/s | 8+ | 32C/64G | ES 20TB/d |
存储空间估算:
每个 Span 平均大小: 2-5KB (含 Tags/Logs)
每日 Trace 量: 1 亿 Span
每日存储: 1亿 × 3KB × 1.5(ES 索引开销) × 2(副本) ≈ 900GB/天
优化:增加采样率、缩短保留期、降低副本数
25 SkyWalking 与 Jaeger 的核心区别是什么?如何选择?
答案:
SkyWalking 和 Jaeger 都是 APM 工具,但在定位、功能和生态上有明显差异。
综合对比:
| 维度 | SkyWalking | Jaeger |
|---|---|---|
| 定位 | APM 平台 | 分布式 Tracing 系统 |
| 社区归属 | Apache | CNCF(毕业) |
| Agent 无侵入 | 是(字节码增强) | 否(SDK 埋点) |
| 自动埋点 | 强大(数十种框架) | 依赖 OTel 或手动 |
| 告警引擎 | 内置 | 无(需扩展) |
| UI 功能 | 丰富(拓扑/仪表盘/分析) | 基础(Trace 查询) |
| Metrics | 内置 | 需配合 Prometheus |
| 存储 | ES/MySQL/TiDB/BanyanDB | Badger/ES/Cassandra/Kafka |
| Service Mesh | Istio 支持完善 | 基础 |
| Profile | 内置代码级分析 | 无 |
| 部署复杂度 | 中 | 低 |
| 生态扩展 | 插件机制 | OTel 集成 |
选型建议:
| 场景 | 推荐 | 原因 |
|---|---|---|
| Java 微服务 | SkyWalking | 自动埋点完善 |
| 多语言环境 | Jaeger + OTel | OTel 标准化 |
| 需要完整 APM | SkyWalking | 内置 Metrics + 告警 |
| 轻量 Tracing | Jaeger | 部署简单 |
| Service Mesh | SkyWalking | Istio 集成完善 |
| 代码级性能 | SkyWalking Profile | 内置火焰图 |
| 已有 OTel | Jaeger | 原生 OTLP 支持 |
26 SkyWalking 的 Trace 查询 GraphQL API 如何调用?
答案:
SkyWalking 提供 GraphQL API 用于查询 Trace、Metrics、拓扑等数据,用于自定义集成和自动化。
API 端点:
OAP REST 端口: 12800
GraphQL 端点: http://oap:12800/graphql
查询 Trace:
# 按条件查询 Trace 列表
query queryBasicTraces($condition: TraceQueryCondition) {
queryBasicTraces(condition: $condition) {
traces {
key: traceId
endpointNames
duration
start
isError
traceIds
}
total
}
}
# 变量
{
"condition": {
"queryDuration": {
"start": "2026-05-26 09:00",
"end": "2026-05-26 10:00"
},
"traceState": "ALL",
"paging": {
"pageNum": 1,
"pageSize": 20,
"needTotal": true
},
"queryOrder": "BY_DURATION",
"tags": [
{
"key": "status_code",
"value": "500"
}
]
}
}
查询 Trace 详情:
query queryTrace($traceId: ID!) {
queryTrace(traceId: $traceId) {
spans {
spanId
parentSpanId
startTime
endTime
operationName
isError
layer
tags {
key
value
}
logs {
time
data {
key
value
}
}
refs {
traceId
parentSegmentId
parentSpanId
type
}
}
}
}
查询拓扑:
query queryTopology($duration: Duration!) {
getAllServices(duration: $duration) {
id
name
}
getAllServiceDependencies(duration: $duration) {
source {
id
name
}
target {
id
name
}
detail {
cpm
avgResponseTime
sla
}
}
}
27 SkyWalking 的集群管理功能:健康检查、配置热更新和故障转移?
答案:
SkyWalking OAP Server 提供集群内健康检查、动态配置管理和故障转移能力。
健康检查:
# 启用健康检查端点
health-checker:
selector: ${SW_HEALTH_CHECKER:default}
default:
checkIntervalSeconds: ${SW_HEALTH_CHECK_INTERVAL_SECONDS:5}
# 健康检查端点
# http://oap:12800/health
# http://oap:12800/health/instance
# 响应示例
{
"healthy": true,
"modules": [
{"name": "receiver-grpc", "state": "RUNNING"},
{"name": "receiver-http", "state": "RUNNING"},
{"name": "storage", "state": "RUNNING"},
{"name": "alarm", "state": "RUNNING"}
],
"liveness": "UP",
"readiness": "READY"
}
配置热更新:
# OAP 配置支持通过 Apollo 或 ZK 动态更新
configuration:
selector: ${SW_CONFIGURATION:grpc}
grpc:
host: ${SW_CONFIG_GRPC_HOST:localhost}
port: ${SW_CONFIG_GRPC_PORT:8080}
period: ${SW_CONFIG_GRPC_PERIOD:60}
# 动态可调整的配置
# - trace 采样率
# - 告警规则
# - 存储 TTL
# - Agent 端配置
故障转移机制:
Agent 连接故障转移:
Agent → OAP-1 (primary)
OAP-2 (backup)
OAP-3 (backup)
当 OAP-1 故障:
Agent 自动切换到 OAP-2
无数据丢失(Agent 缓冲队列)
OAP-1 恢复后重新负载
OAP 集群故障转移:
OAP 之间通过 Cluster Coordinator 监测
节点故障 → 业务转移给健康节点
数据从存储层读取(存储层 HA)
28 SkyWalking 的 BanyanDB 原生数据库与 ES 方案的区别?
答案:
BanyanDB 是 SkyWalking 社区自研的时序数据库,专为 APM 数据模型优化。
BanyanDB vs Elasticsearch:
| 维度 | Elasticsearch | BanyanDB |
|---|---|---|
| 定位 | 通用搜索引擎 | APM 原生时序 DB |
| 数据模型 | 倒排索引 + 文档 | 流式 + 时序列式 |
| 写入性能 | 高 | 极高 |
| 压缩比 | 2-5× | 10-15× |
| 存储成本 | 高 | 低 |
| 查询语言 | DSL / SQL | 原生 API + PromQL |
| 运维 | 复杂 | 简单 |
| 集群一致性 | 最终 | 强 |
| APM 适配 | 通用 | SkyWalking 原生 |
BanyanDB 部署:
# docker-compose
version: '3'
services:
banyandb:
image: apache/skywalking-banyandb:latest
ports:
- "17912:17912" # gRPC
- "17913:17913" # HTTP
environment:
- SW_STORAGE_BANYANDB_HOST=0.0.0.0
- SW_STORAGE_BANYANDB_GRPC_PORT=17912
volumes:
- ./banyandb-data:/data
oap:
image: apache/skywalking-oap-server:latest
environment:
- SW_STORAGE=banyandb
- SW_STORAGE_BANYANDB_HOST=banyandb
- SW_STORAGE_BANYANDB_GRPC_PORT=17912
BanyanDB 优势:
1. 更低存储成本
- 专门为 Trace/Metrics 数据模型优化
- 列式压缩,压缩比 10-15×
2. 更高写入性能
- 流式写入(非索引写)
- 无倒排索引构建开销
3. 更简单运维
- 单二进制部署
- 无 JVM 依赖
- 自动 TTL
4. 原生 APM 数据模型
- Trace/Metrics/Log 原生支持
- 无需 mapping 定义
29 SkyWalking 的 eBPF 监控(Rover)实现原理是什么?
答案:
SkyWalking Rover 是基于 eBPF 的零侵扰监控代理,对 Linux 内核层进行网络和系统调用监控。
Rover 监控架构:
graph TD
HN["Host/Node"] --> SR["SkyWalking Rover<br/>eBPF"]
SR --> NM["Network Monitor<br/>TCP/UDP<br/>连接追踪"]
SR --> PM["Process/Syscall Monitor<br/>Exec/Libc<br/>调用追踪"]
NM --> OAP["OAP Server<br/>数据接收与分析"]
PM --> OAP
eBPF 采集数据:
// eBPF 程序示例:TCP 连接追踪
SEC("kprobe/tcp_connect")
int trace_connect(struct pt_regs *ctx) {
struct sock *sk;
sk = (struct sock *)PT_REGS_PARM1(ctx);
// 记录连接事件
u32 src_ip = BPF_CORE_READ(sk, __sk_common.skc_rcv_saddr);
u32 dst_ip = BPF_CORE_READ(sk, __sk_common.skc_daddr);
u16 dst_port = BPF_CORE_READ(sk, __sk_common.skc_dport);
// 发送到用户态
bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU,
&evt, sizeof(evt));
return 0;
}
Rover 能力:
| 功能 | 说明 | 传统 Agent 对比 |
|---|---|---|
| 网络拓扑 | TCP 连接自动发现 | 无需应用代码 |
| 延迟监控 | 内核级 TCP 延迟 | 精度更高 |
| HTTP 解析 | HTTP/1.1, HTTP/2, gRPC | 部分支持 |
| TLS 解密 | 需配置 | 不支持 |
| 进程监控 | 进程创建/销毁 | 无法 |
| 系统调用 | 关键 syscall 追踪 | 无法 |
适用场景:
优势:
- 不支持 Agent 的语言(如 C/C++/Rust)
- 遗留系统(无法修改)
- Sidecar 容器(Envoy 协议)
局限:
- 只能追踪网络层(无应用层语义)
- HTTP body 内容有限
- 需 Linux 4.9+ 内核
- root 权限运行
30 SkyWalking 的扩展机制:自定义插件开发和配置方法?
答案:
SkyWalking 提供插件扩展机制,支持开发者编写自定义 Agent 插件拦截特定框架。
插件开发步骤:
// 1. 定义拦截点注解
@AgentCacheDeclaration
public class MyFrameworkPlugin extends AbstractClassEnhancePluginDefine {
@Override
protected ClassMatch enhanceClass() {
// 匹配目标类
return NameMatch.byName("com.example.MyClient");
}
@Override
public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
// 构造函数拦截点
return null;
}
@Override
public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
// 实例方法拦截点
return new InstanceMethodsInterceptPoint[] {
new InstanceMethodsInterceptPoint() {
@Override
public ElementMatcher<MethodDescription> getMethodsMatcher() {
return named("sendRequest");
}
@Override
public String getMethodsInterceptor() {
return "com.example.MyInterceptor";
}
@Override
public boolean isOverrideArgs() {
return false;
}
}
};
}
}
Interceptor 实现:
public class MyInterceptor implements InstanceMethodsAroundInterceptor {
@Override
public void beforeMethod(EnhancedInstance objInst, Method method,
Object[] allArguments, Class<?>[] argumentsTypes) {
// 创建 Exit Span
AbstractSpan span = ContextManager.createExitSpan(
"MyClient/sendRequest",
allArguments[0].toString() // target address
);
span.setComponent(ComponentsDefine.MY_FRAMEWORK);
}
@Override
public Object afterMethod(EnhancedInstance objInst, Method method,
Object[] allArguments, Class<?>[] argumentsTypes,
Object ret) {
ContextManager.stopSpan();
return ret;
}
@Override
public void handleMethodException(EnhancedInstance objInst, Method method,
Object[] allArguments, Class<?>[] argumentsTypes,
Throwable t) {
ContextManager.activeSpan().log(t);
}
}
插件打包和部署:
<!-- pom.xml 插件打包 -->
<project>
<dependencies>
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-agent-core</artifactId>
<version>${skywalking.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
<!-- 部署到 Agent 插件目录 -->
cp my-plugin.jar /path/to/agent/plugins/
插件目录结构:
agent/
├── activations/ # 激活插件
├── bootstrap-plugins/ # 启动插件(核心拦截点)
├── plugins/ # 标准插件(自动加载)
│ ├── apm-tomcat-xx.jar
│ ├── apm-spring-xx.jar
│ ├── apm-jdbc-xx.jar
│ └── my-plugin.jar ← 自定义插件
└── config/
└── agent.config