跳转到内容

SkyWalking 面试题

30 道题
分类
可观测性
子分类
trace
题目数
30 道
已阅读 0 / 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

支持的框架拦截:

类型框架
HTTPTomcat, Jetty, Undertow, Spring MVC
gRPCgRPC 全版本
RPCDubbo, gRPC, Motan, SOFARPC
MQKafka, RabbitMQ, RocketMQ, Pulsar
DBJDBC, MongoDB, Redis, Elasticsearch
CloudSpring 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单个操作单元操作级
SpanRefSpan 间的父子/跨进程引用关联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 AnalyzerTrace 数据分析注册到 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 支持多种存储后端,不同存储方案影响查询性能、存储成本和运维复杂度。

存储方案对比:

维度ElasticsearchMySQL / PostgreSQLTiDBBanyanDB
定位通用搜索引擎关系型数据库分布式数据库时序数据库
查询性能极高极高
写入性能极高
存储成本
运维复杂度
集群模式原生需 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 / PostgreSQL1-3
1-10 亿Elasticsearch3-9
10-100 亿TiDB / BanyanDB3-15
> 100 亿BanyanDB5+
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 状态维护者自动埋点能力
JavaGA(生产可用)官方强(字节码增强)
GoGA官方中(手动+自动)
Node.jsGA官方
PythonGA社区
LuaBeta社区Nginx/OpenResty
.NETBeta社区
PHPAlpha社区基础
C++Alpha社区基础
RustAlpha社区基础

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 作为默认高性能通信方式。

协议对比:

维度gRPCHTTP
传输层HTTP/2HTTP/1.1
编码ProtobufJSON
性能高(二进制、流式)
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]

关系定位:

维度SkyWalkingOpenTelemetry
定位APM 平台(完整方案)遥测标准(API/SDK)
组件范围Agent + OAP + UI + 告警API + SDK + Collector
可视化内置 UI依赖 Grafana 等
告警内置告警引擎需外部告警系统
Trace 协议自有协议 + OTLPOTLP
互操作性支持 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_slaAPI 级别

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}

字段说明:

位置字段说明示例
1Version协议版本1
2Trace ID全局 Trace IDabc123...
3Segment ID上游 Segment IDseg-xyz...
4Span ID上游 Span ID1
5Service上游服务名user-service
6Instance上游实例user-1
7Endpoint上游端点GET /api/users
8Target Address目标地址10.0.1.5:8080
9Correlation关联数据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说明
Sw8sw8SkyWalking 原生
Sw8-xsw8-x扩展协议
W3C TraceContexttraceparentOTel 兼容
B3b3 / 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/Trace3-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服务拓扑图调用关系可视化
TraceTrace 查询和详情慢请求/错误排查
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
SlackWebhook URL海外 IM
飞书机器人 Webhook国内 IM
PagerDutyEvents APIOn-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}作用域 ID1
{id0}第一级 IDuser-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/sTrace 吞吐量
应用延迟影响< 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/s14C/8GES 20GB/d
10k Spans/s28C/16GES 200GB/d
100k Spans/s416C/32GES 2TB/d
1M Spans/s8+32C/64GES 20TB/d

存储空间估算:

每个 Span 平均大小: 2-5KB (含 Tags/Logs)
每日 Trace 量: 1 亿 Span
每日存储: 1亿 × 3KB × 1.5(ES 索引开销) × 2(副本) ≈ 900GB/天

优化:增加采样率、缩短保留期、降低副本数
25 SkyWalking 与 Jaeger 的核心区别是什么?如何选择?

答案:

SkyWalking 和 Jaeger 都是 APM 工具,但在定位、功能和生态上有明显差异。

综合对比:

维度SkyWalkingJaeger
定位APM 平台分布式 Tracing 系统
社区归属ApacheCNCF(毕业)
Agent 无侵入是(字节码增强)否(SDK 埋点)
自动埋点强大(数十种框架)依赖 OTel 或手动
告警引擎内置无(需扩展)
UI 功能丰富(拓扑/仪表盘/分析)基础(Trace 查询)
Metrics内置需配合 Prometheus
存储ES/MySQL/TiDB/BanyanDBBadger/ES/Cassandra/Kafka
Service MeshIstio 支持完善基础
Profile内置代码级分析
部署复杂度
生态扩展插件机制OTel 集成

选型建议:

场景推荐原因
Java 微服务SkyWalking自动埋点完善
多语言环境Jaeger + OTelOTel 标准化
需要完整 APMSkyWalking内置 Metrics + 告警
轻量 TracingJaeger部署简单
Service MeshSkyWalkingIstio 集成完善
代码级性能SkyWalking Profile内置火焰图
已有 OTelJaeger原生 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:

维度ElasticsearchBanyanDB
定位通用搜索引擎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