当前位置: 首页 > news >正文

skywalking 原理

好的,我们来深入解析 Apache SkyWalking 的原理。它的设计非常精巧,核心思想是**通过分布式追踪技术,在复杂的分布式系统中清晰地还原一个请求的完整调用链,并在此之上构建强大的监控能力**。

为了让您更容易理解,我将从以下几个核心部分来阐述其原理:

1.  **整体架构与工作流程**
2.  **核心概念:什么是 Tracing?**
3.  **数据采集与自动探针(Agent)原理**
4.  **数据流与存储(OAP)原理**
5.  **数据分析与聚合原理**
6.  **可视化(UI)原理**

---

### 1. 整体架构与工作流程

SkyWalking 采用经典的**客户端-服务端**架构,如下图所示(精简版):


```
[您的应用] -> [SkyWalking Agent] --(gRPC)--> [SkyWalking OAP Server] --(GraphQL)--> [SkyWalking UI]
|
|--(写入)--> [存储集群] (Elasticsearch, TiDB, H2...)
```

**工作流程简述:**
1.  **注入探针**:在您的应用(Java, Go, .NET, PHP 等)中通过 `-javaagent` 或相关方式植入 SkyWalking Agent。
2.  **收集数据**:Agent 会**无侵入地**收集应用的性能数据(如调用链、指标、日志)。
3.  **上报数据**:Agent 将数据通过 **gRPC**(默认)或 HTTP 协议上报给 SkyWalking OAP (Observability Analysis Platform) 服务器。
4.  **流式分析**:OAP 服务器接收到数据后,会进行**实时流式分析**(使用 MAL 等脚本),对数据进行聚合、计算、丰富。
5.  **持久化存储**:分析后的数据被持久化到后端的存储中,如 Elasticsearch、MySQL (TiDB)、H2 等。
6.  **可视化展示**:用户通过 SkyWalking UI 查询数据,UI 会向 OAP 服务器发送 GraphQL 查询请求,并将结果以图表、拓扑图、列表等形式展示出来。

---

### 2. 核心概念:什么是 Tracing?

要理解 SkyWalking,必须先理解 **Tracing**(追踪)。

*   **Trace**:代表一个**完整的请求链路**。例如,用户从浏览器点击一个按钮,这个请求从网关 -> 认证服务 -> 订单服务 -> 支付服务 -> 数据库,这一整条路径就是一个 Trace。
*   **Span**:代表一个**工作单元**,是 Trace 中的单个节点。例如,订单服务处理这个请求就是一个 Span。每个 Span 包含:
*   `Trace ID`:全局唯一,用于串联整个请求的所有 Span。
*   `Span ID`:当前工作单元的唯一标识。
*   `Parent Span ID`:父工作单元的 ID,用于构建树形结构。
*   `Operation Name`:操作名(如 `GET:/order/{id}`)。
*   `Start Time` & `End Time`:时间戳,用于计算耗时。
*   `Tags`:键值对,记录上下文信息(如 `http.status_code=200`, `db.instance=mysql`)。
*   `Logs`:时间戳事件,用于记录特定时刻的信息(如错误堆栈)。
*   **Context Propagation**(上下文传播):这是分布式追踪的魔法所在。当一个服务调用另一个服务时,`Trace ID`、`Parent Span ID` 等信息会通过 **HTTP Headers**(如 `sw8`)或 **RPC 上下文**传递给下游服务,从而将整个调用链串起来。

---

### 3. 数据采集与自动探针(Agent)原理

这是 SkyWalking **无侵入性** 的关键。

*   **字节码增强(Byte Buddy)**:SkyWalking Agent 主要通过在**运行时**修改应用程序的字节码来收集数据。它不需要你修改任何业务代码。
*   **如何工作**:
1.  当 JVM 启动时,`-javaagent` 参数会优先加载 SkyWalking Agent。
2.  Agent 会定义一系列**拦截点**(例如,所有 `HttpClient.execute()` 方法、所有 `@RestController` 类的方法、所有 JDBC 的 `executeQuery` 方法等)。
3.  当你的应用代码执行到这些拦截点时,Agent 会在**方法执行前**和**方法执行后**插入自己的监控代码。
4.  这些插入的代码会负责**创建 Span**、**记录开始时间**、**捕获异常**、**添加标签**,并在方法执行结束时**记录结束时间**,最后将 Span 数据放入缓冲区。
*   **性能开销极低**:所有操作都是内存操作,且采用**异步上报**模式(Agent 将数据先放入缓冲区,再由单独线程批量发送给 OAP),因此对应用性能的影响非常小(官方宣称资源开销 < 10%)。

---

### 4. 数据流与存储(OAP)原理

OAP 服务器是大脑,负责处理和存储数据。

*   **Receiver**:接收器模块,负责从 Agent 接收不同格式的数据(如 SkyWalking 原生格式、Zipkin、Jaeger、OpenTelemetry 格式)。
*   **Parser**:解析器,将接收到的数据解析成内部的流数据模型。
*   **Streaming Core**(流式核心):这是最核心的部分。它使用 **MAL (Meter Analysis Language)** 等配置对数据流进行**实时分析**。
*   **聚合**:例如,将一秒内的所有“订单服务”的指标数据聚合起来,计算该秒的总请求数、平均耗时、错误数等。
*   **计算**:根据原始数据计算出衍生指标,如 Apdex、SLA、P99 延迟等。
*   **丰富**:将不同数据流关联起来,例如将 JVM 指标关联到对应的服务实例上。
*   **Storage**:存储模块。处理后的数据会被分门别类地保存到存储集群中。
*   **时序数据**(指标):存储在 ES 等,用于绘制曲线图。
*   **明细数据**(追踪链):存储在 ES 等,用于查询具体某次请求的详情。
*   **元数据**(服务、实例列表):通常也存储在 ES 或关系型数据库中。

---

### 5. 数据分析与聚合原理

这是产生强大监控能力的关键。

*   **Top N 计算**:OAP 不会存储所有原始数据(那样成本太高),而是按时间窗口(如1分钟)进行预聚合。例如,它会计算出一分钟内:
*   哪个端点(Endpoint)最慢?(Slow Endpoint List)
*   哪个服务错误率最高?
*   **指标派生**:
*   **Apdex**:根据配置的阈值 T,分析延迟数据分布计算得出。
*   **百分位数(P99, P95...)**:使用 **TDigest** 或 **AvgHistogram** 等算法对延迟数据进行流式计算,以高效且近似地得到百分位数值,而不需要保存所有原始数据点。
*   **拓扑分析**:通过分析 Trace 数据中的服务间调用关系(`Tags` 和 `Logs` 中的网络地址信息),OAP 可以自动绘制出**服务依赖关系拓扑图**。

---

### 6. 可视化(UI)原理

UI 是最终展示层。

*   **GraphQL API**:UI 不直接查询数据库,而是向 OAP 服务器发送 **GraphQL** 查询请求。GraphQL 允许 UI 精确地指定它需要哪些数据,避免了 REST API 的“过度获取”或“获取不足”的问题。
*   **查询过程**:当你在 UI 上选择“过去1小时”、“服务A”的“平均响应时间”时:
1.  UI 会构建一个对应的 GraphQL 查询。
2.  OAP 服务器接收到查询,解析后向存储集群(如 ES)发起请求。
3.  从 ES 获取到聚合好的时序数据后,返回给 UI。
4.  UI 使用 ECharts 等图形库将数据渲染成曲线图。

### 总结

SkyWalking 的原理可以概括为:

1.  **无侵入采集**:通过**字节码增强技术**在运行时自动埋点,收集追踪和指标数据。
2.  **上下文传播**:通过 **HTTP Headers** 传递 `Trace ID`,将分散的服务调用串联成完整的调用链。
3.  **流式处理**:服务端对海量数据进行**实时聚合和计算**,生成指标、拓扑、告警等高级信息。
4.  **集中存储与查询**:将处理后的结果存入高性能存储,并通过 **GraphQL API** 提供给 UI 进行灵活的可视化展示。

这种设计使得 SkyWalking 既能提供强大的分布式追踪和监控能力,又能保持对应用的低侵入性和低性能影响。

http://www.xdnf.cn/news/1373707.html

相关文章:

  • 当AI有了温度,三星正在重新定义生活的边界
  • 技术分析 | Parasoft C/C++test如何突破单元测试的隔离难题
  • SyntaxError: Failed to execute ‘open‘ on ‘XMLHttpRequest‘: Invalid URL
  • 【C++】set 容器的使用
  • Android/Java中枚举的详解
  • 基于Spring Boot+Vue的生活用品购物平台/在线购物系统/生活用户在线销售系统/基于javaweb的在线商城系统
  • JMeter —— 压力测试
  • 基于 Docker Compose 的若依多服务一键部署java项目实践
  • C# OpenCVSharp 实现物体尺寸测量方案
  • 【Java】异常处理:从入门到精通
  • npm run start 的整个过程
  • 文字样式设置
  • Python基础、数据科学入门NumPy(数值计算)、Pandas(数据处理)、Matplotlib(数据可视化)附视频教程
  • 使用Spring Boot和EasyExcel导出Excel文件,并在前端使用Axios进行请求
  • 部署网页在服务器(公网)上笔记 infinityfree 写一个找工作单html文件的网站
  • 趣味学Rust基础篇(变量与可变性)
  • 从传统到创新:用报表插件重塑数据分析平台
  • 基于Spark的白酒行业数据分析与可视化系统的设计与实现
  • 【服务器】用X99主板组装服务器注意事项
  • 【开题答辩全过程】以 微信小程序的医院挂号预约系统为例,包含答辩的问题和答案
  • 在Excel和WPS表格中通过查找替换对单元格批量强制换行
  • 实现基于数据库 flag 状态的消息消费控制
  • PMP项目管理知识点-⑭【①-⑬流程总结】→图片直观表示
  • 让ai写一个类github首页
  • 从文本到二进制:HTTP/2不止于性能,更是对HTTP/1核心语义的传承与革新
  • 深度学习11 Deep Reinforcement Learning
  • 深度学习12 Reinforcement Learning with Human Feedback
  • 如何在阿里云百炼中使用钉钉MCP
  • 深度学习——激活函数
  • 【stm32简单外设篇】-4×4 薄膜键盘