在这里插入图片描述

👋 大家好,欢迎来到我的技术博客!
📚 在这里,我会分享学习笔记、实战经验与技术思考,力求用简单的方式讲清楚复杂的问题。
🎯 本文将围绕SkyWalking这个话题展开,希望能为你带来一些启发或实用的参考。
🌱 无论你是刚入门的新手,还是正在进阶的开发者,希望你都能有所收获!


文章目录

SkyWalking - 快速上手:5 分钟部署 SkyWalking 并监控一个 Spring Boot 应用 🚀

在当今微服务架构盛行的时代,分布式系统的可观测性(Observability)已成为保障系统稳定性和性能优化的关键能力。Apache SkyWalking 作为一款开源的 APM(Application Performance Monitoring)工具,以其轻量级、无侵入、高性能的特点,在云原生和微服务监控领域迅速崛起。🎯

本篇博客将带你从零开始,仅用 5 分钟完成 SkyWalking 的部署,并将其接入一个真实的 Spring Boot 应用中,实现端到端的链路追踪、性能指标采集与可视化展示。无论你是 DevOps 工程师、后端开发者还是架构师,这篇文章都将为你提供实用、可落地的操作指南。


💡 什么是 SkyWalking?

Apache SkyWalking 是由国人吴晟主导开发并捐赠给 Apache 基金会的顶级项目,是一款专为微服务、云原生和容器化环境设计的应用性能监控与诊断平台。它支持自动探针(Agent)注入,无需修改业务代码即可实现:

  • 分布式链路追踪(Distributed Tracing)
  • 性能指标监控(Metrics Collection)
  • 拓扑关系分析(Topology Mapping)
  • 服务依赖分析
  • 异常告警与日志关联

SkyWalking 支持 Java、.NET、Node.js、Go、PHP、Python 等多种语言,同时兼容 OpenTracing、OpenTelemetry 等标准协议,是现代云原生架构下不可或缺的“眼睛”。

官方网站:https://skywalking.apache.org/


🧱 架构概览(含 Mermaid 图表)

在动手之前,我们先通过一张架构图理解 SkyWalking 的核心组件及其协作方式:

1. Inject Agent
2. Send Trace & Metrics
3. Store Data
4. Query API
5. Visualize

Alerts, Logs

Spring Boot App

SkyWalking Agent

OAP Server

Storage: Elasticsearch / H2 / MySQL

UI Dashboard

Browser

Other Services

External Systems

📌 说明

  • Agent:以 Java Agent 形式挂载在应用 JVM 上,负责采集调用链、方法耗时、异常等数据。
  • OAP Server(Observability Analysis Platform):接收 Agent 数据,进行聚合、分析、存储。
  • Storage:默认使用 H2(开发)或 Elasticsearch(生产),也可选 MySQL、TiDB 等。
  • UI:基于 Vue.js 的可视化界面,提供拓扑图、链路追踪、仪表盘等功能。

⏱️ 第一步:下载并启动 SkyWalking(1分钟)

我们选择最简方式 —— 使用官方提供的二进制包 + 内置 H2 数据库(适合快速体验)。

✅ 下载最新版本

前往官方下载页获取最新稳定版(写作时为 v9.7.0):

wget https://archive.apache.org/dist/skywalking/9.7.0/apache-skywalking-apm-9.7.0.tar.gz
tar -zxvf apache-skywalking-apm-9.7.0.tar.gz
cd apache-skywalking-apm-bin

提示:你也可以访问 https://skywalking.apache.org/downloads/ 获取最新版本。

✅ 启动 OAP Server 和 UI

SkyWalking 自带两个启动脚本:

# 启动后端服务(OAP)
bin/oapService.sh

# 启动前端 UI(默认端口 8080)
bin/webappService.sh

💡 小贴士:如果你希望后台运行,可以使用 nohupscreen

nohup bin/oapService.sh > oap.log 2>&1 &
nohup bin/webappService.sh > ui.log 2>&1 &

等待约 30 秒,访问 http://localhost:8080 即可看到 SkyWalking 登录界面(默认无密码)。


☕ 第二步:创建一个 Spring Boot 示例应用(2分钟)

我们快速搭建一个简单的 REST API 应用,用于演示 SkyWalking 的监控能力。

✅ 初始化项目结构

使用 Spring Initializr 创建一个基础 Web 项目,或手动创建如下结构:

demo-skywalking/
├── pom.xml
└── src/
    └── main/
        ├── java/
        │   └── com/example/demo/
        │       ├── DemoApplication.java
        │       └── controller/
        │           └── HelloController.java
        └── resources/
            └── application.yml

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>demo-skywalking</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.1.5</version>
        <relativePath/>
    </parent>

    <properties>
        <java.version>17</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

DemoApplication.java

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

HelloController.java

package com.example.demo.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {

    private static final Logger logger = LoggerFactory.getLogger(HelloController.class);

    @GetMapping("/hello")
    public String sayHello(@RequestParam(defaultValue = "World") String name) {
        logger.info("Received request for name: {}", name);
        simulateProcessing();
        return "Hello, " + name + "! Welcome to SkyWalking!";
    }

    private void simulateProcessing() {
        try {
            Thread.sleep(200); // 模拟业务处理耗时
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

application.yml

server:
  port: 8081

spring:
  application:
    name: demo-skywalking-app

management:
  endpoints:
    web:
      exposure:
        include: "*"
  endpoint:
    health:
      show-details: always

✅ 打包并运行(不带 SkyWalking)

mvn clean package
java -jar target/demo-skywalking-0.0.1-SNAPSHOT.jar

访问 http://localhost:8081/hello?name=SkyWalking,应返回:

Hello, SkyWalking! Welcome to SkyWalking!

✅ 应用正常运行,准备接入监控!


🎯 第三步:接入 SkyWalking Agent(1分钟)

现在是最关键的一步 —— 让你的 Spring Boot 应用被 SkyWalking 监控起来!

✅ 复制 Agent 文件夹

从你之前解压的 SkyWalking 包中,复制 agent 文件夹到你的项目根目录:

cp -r /path/to/apache-skywalking-apm-bin/agent ./skywalking-agent

✅ 修改 Agent 配置(可选)

默认配置已足够,但你可以根据需要调整 skywalking-agent/config/agent.config

# 应用名称(会在 UI 中显示)
agent.service_name=${SW_AGENT_NAME:demo-skywalking-app}

# OAP 服务器地址
collector.backend_service=${SW_AGENT_COLLECTOR_BACKEND_SERVICES:127.0.0.1:11800}

# 日志级别
logging.level=${SW_LOGGING_LEVEL:INFO}

✅ 启动应用并挂载 Agent

只需在 java -jar 命令前加上 -javaagent 参数:

java -javaagent:./skywalking-agent/skywalking-agent.jar \
     -Dskywalking.agent.service_name=demo-app \
     -Dskywalking.collector.backend_service=127.0.0.1:11800 \
     -jar target/demo-skywalking-0.0.1-SNAPSHOT.jar

🎉 成功!控制台将输出类似以下内容:

SkyWalking Agent start success.

此时,你的应用已被 SkyWalking 监控!


📊 第四步:查看监控数据(1分钟)

打开浏览器,访问 http://localhost:8080

🔍 查看服务列表

左侧导航栏 → “服务” → 应该能看到 demo-app 已注册。

🌐 查看拓扑图

点击顶部 “拓扑图”,你会看到一个节点图,代表当前被监控的服务及其调用关系(目前只有一个节点)。

📈 查看链路追踪

访问几次你的接口:

curl "http://localhost:8081/hello?name=Alice"
curl "http://localhost:8081/hello?name=Bob"

然后进入 “追踪” 页面,选择服务 demo-app,即可看到每次请求的完整调用链:

GET /hello
├── Controller.sayHello (200ms)
└── Logger.info (1ms)

每个 Span 都包含耗时、状态、标签等信息,点击可展开详情。

📉 查看性能指标

进入 “仪表盘” → 选择 “服务”,你可以看到:

  • 请求量(Throughput)
  • 平均响应时间(Response Time)
  • 成功率(Success Rate)
  • JVM 内存/CPU 使用情况

🛠️ 进阶:模拟多服务调用(可选)

为了更真实地展示 SkyWalking 的分布式追踪能力,我们可以创建第二个服务,并让第一个服务调用它。

✅ 创建第二个服务 user-service

结构类似,端口改为 8082:

@RestController
public class UserController {
    @GetMapping("/user/{id}")
    public Map<String, Object> getUser(@PathVariable String id) {
        try {
            Thread.sleep(150); // 模拟数据库查询
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        return Map.of(
            "id", id,
            "name", "User-" + id,
            "email", "user" + id + "@example.com"
        );
    }
}

✅ 在第一个服务中调用它

HelloController 中注入 RestTemplate

@Autowired
private RestTemplate restTemplate;

@GetMapping("/hello-with-user")
public String helloWithUser(@RequestParam String userId) {
    String url = "http://localhost:8082/user/" + userId;
    ResponseEntity<Map> response = restTemplate.getForEntity(url, Map.class);
    String userName = (String) response.getBody().get("name");
    return "Hello, " + userName + "! Your data is loaded via distributed call.";
}

别忘了在主类中注册 RestTemplate

@Bean
public RestTemplate restTemplate() {
    return new RestTemplate();
}

分别启动两个服务(都挂载 SkyWalking Agent):

# Terminal 1
java -javaagent:./skywalking-agent/skywalking-agent.jar \
     -Dskywalking.agent.service_name=demo-app \
     -jar target/demo-skywalking-0.0.1-SNAPSHOT.jar

# Terminal 2
java -javaagent:./skywalking-agent/skywalking-agent.jar \
     -Dskywalking.agent.service_name=user-service \
     -jar target/user-service-0.0.1-SNAPSHOT.jar

访问:

curl "http://localhost:8081/hello-with-user?userId=1001"

回到 SkyWalking UI → “追踪”,你将看到跨服务的完整调用链:

user-service demo-app Client user-service demo-app Client GET /hello-with-user?userId=1001 GET /user/1001 {id:1001, name:User-1001...} Hello, User-1001! ...

这正是分布式链路追踪的核心价值 —— 跨进程、跨服务的请求路径一目了然!


🧪 自定义埋点与注解监控

虽然 SkyWalking 默认支持 Spring MVC、Feign、Dubbo 等框架的自动埋点,但在某些场景下,你可能希望手动记录关键方法或业务逻辑的耗时。

✅ 使用 @Trace 注解

SkyWalking 提供了一个简单的注解 @Trace,可用于标记需要追踪的方法。

首先添加依赖(如果你使用 Maven):

<dependency>
    <groupId>org.apache.skywalking</groupId>
    <artifactId>apm-toolkit-trace</artifactId>
    <version>8.15.0</version>
</dependency>

然后在方法上添加注解:

import org.apache.skywalking.apm.toolkit.trace.Trace;

@Service
public class BusinessService {

    @Trace
    public String processOrder(String orderId) {
        simulateHeavyWork();
        return "Order " + orderId + " processed successfully";
    }

    private void simulateHeavyWork() {
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

在 Controller 中调用:

@GetMapping("/order/{id}")
public String processOrder(@PathVariable String id) {
    return businessService.processOrder(id);
}

重启应用后,访问 /order/123,在追踪页面中你将看到新增的 Span:“BusinessService.processOrder”。

✅ 手动创建 Span(高级用法)

对于更精细的控制,可以使用 SkyWalking 的 API 手动创建 Span:

import org.apache.skywalking.apm.toolkit.trace.TraceContext;
import org.apache.skywalking.apm.toolkit.trace.TraceSegmentRef;

public String complexWorkflow(String input) {
    AbstractSpan span = TraceContext.createLocalSpan("complexWorkflow");
    span.setTag("input.value", input);

    try {
        stepOne(input);
        stepTwo(input);
        return "Success";
    } catch (Exception e) {
        span.log(e);
        span.errorOccurred();
        throw e;
    } finally {
        span.finish();
    }
}

这种方式适用于异步任务、消息队列消费、定时任务等非 HTTP 请求场景。


📦 生产建议:使用 Elasticsearch 存储

默认的 H2 数据库仅适用于开发和测试,生产环境强烈建议使用 Elasticsearch。

✅ 安装 Elasticsearch

推荐使用 Docker 快速部署:

docker run -d --name es-skywalking \
  -p 9200:9200 -p 9300:9300 \
  -e "discovery.type=single-node" \
  -e "ES_JAVA_OPTS=-Xms512m -Xmx512m" \
  docker.elastic.co/elasticsearch/elasticsearch:7.17.0

✅ 修改 SkyWalking 存储配置

编辑 config/application.yml

storage:
  selector: ${SW_STORAGE:elasticsearch}
  elasticsearch:
    namespace: ${SW_NAMESPACE:""}
    clusterNodes: ${SW_STORAGE_ES_CLUSTER_NODES:localhost:9200}
    protocol: ${SW_STORAGE_ES_HTTP_PROTOCOL:"http"}
    indexShardsNumber: ${SW_STORAGE_ES_INDEX_SHARDS_NUMBER:1}
    indexReplicasNumber: ${SW_STORAGE_ES_INDEX_REPLICAS_NUMBER:0}

重启 OAP Server:

bin/oapService.sh

SkyWalking 将自动在 ES 中创建索引,如 service_traffic, segment 等。


📣 告警功能配置

SkyWalking 支持基于规则的告警机制,比如当错误率超过 10% 或响应时间大于 1s 时触发通知。

✅ 编辑告警规则

修改 config/alarm-settings.yml

rules:
  service_resp_time_rule:
    metrics-name: service_resp_time
    op: ">"
    threshold: 1000
    period: 10
    count: 3
    silence-period: 5
    message: Response time of service {name} is more than 1000ms in 3 minutes of last 10 minutes.

  service_sla_rule:
    metrics-name: service_sla
    op: "<"
    threshold: 9000
    period: 10
    count: 3
    silence-period: 5
    message: Successful rate of service {name} is lower than 90% in 3 minutes of last 10 minutes.

✅ 配置通知渠道(Webhook)

SkyWalking 支持 Webhook、Slack、钉钉、企业微信等多种通知方式。

例如配置 Webhook:

webhooks:
  - url: http://your-alert-server/alert
    name: alert-system

你也可以编写自己的告警接收服务:

@RestController
public class AlertReceiverController {

    @PostMapping("/alert")
    public ResponseEntity<String> receiveAlert(@RequestBody List<AlertMessage> alerts) {
        alerts.forEach(alert -> {
            System.out.println("[ALERT] " + alert.getMessage());
            // 发送邮件、短信、企业微信等
        });
        return ResponseEntity.ok("Received");
    }

    public static class AlertMessage {
        private String message;
        private long startTime;
        private String serviceName;

        // getters & setters
    }
}

🌐 与 OpenTelemetry 集成

SkyWalking 从 8.0 版本开始全面支持 OpenTelemetry 协议,这意味着你可以使用 OTel SDK 生成数据,由 SkyWalking OAP 接收并展示。

✅ 启用 OTLP Receiver

config/application.yml 中启用:

receiver_otel:
  selector: ${SW_RECEIVER_OTEL:default}
  default:
    enabled: true

重启 OAP。

✅ 在 Spring Boot 中使用 OTel SDK

添加依赖:

<dependency>
    <groupId>io.opentelemetry</groupId>
    <artifactId>opentelemetry-api</artifactId>
    <version>1.31.0</version>
</dependency>
<dependency>
    <groupId>io.opentelemetry</groupId>
    <artifactId>opentelemetry-sdk</artifactId>
    <version>1.31.0</version>
</dependency>
<dependency>
    <groupId>io.opentelemetry</groupId>
    <artifactId>opentelemetry-exporter-otlp</artifactId>
    <version>1.31.0</version>
</dependency>

初始化 Tracer:

@Configuration
public class OtelConfig {

    @Bean
    public Tracer tracer() {
        Resource resource = Resource.getDefault()
            .merge(Resource.create(Attributes.of(ResourceAttributes.SERVICE_NAME, "demo-app")));

        SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder()
            .addResource(resource)
            .build();

        OpenTelemetry openTelemetry = OpenTelemetrySdk.builder()
            .setTracerProvider(sdkTracerProvider)
            .setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance()))
            .buildAndRegisterGlobal();

        return openTelemetry.getTracer("com.example.demo");
    }
}

在业务代码中使用:

@GetMapping("/otel-test")
public String otelTest() {
    Span span = tracer.spanBuilder("otelTest").startSpan();
    try (Scope scope = span.makeCurrent()) {
        span.setAttribute("user.id", "12345");
        simulateWork();
        return "Traced with OpenTelemetry!";
    } finally {
        span.end();
    }
}

这样,即使不使用 SkyWalking Agent,也能将追踪数据上报至 SkyWalking,实现统一监控。


🧩 插件扩展与自定义

SkyWalking 支持丰富的插件机制,你可以:

  • 开发自定义插件监控特定框架
  • 扩展数据采集维度
  • 修改采样策略

✅ 自定义采样率

agent.config 中设置:

# 采样率,10000 表示 100%,1000 表示 10%
agent.sample_n_per_3_secs=${SW_AGENT_SAMPLE:-10000}

✅ 忽略某些 URL

# 不监控健康检查端点
agent.ignore_suffix=${SW_AGENT_IGNORE_SUFFIX:.jpg,.jpeg,.js,.css,.png,.bmp,.gif,.ico,.mp3,.mp4,.html,.svg,.pdf,/actuator/health}

✅ 开发自定义插件(简要步骤)

  1. 创建 Maven 项目,依赖 skywalking-agent-core
  2. 实现 InstanceMethodsAroundInterceptorStaticMethodsAroundInterceptor
  3. skywalking-plugin.def 中声明插件
  4. 放入 agent/plugins/ 目录

示例:监控 Redis 调用

public class JedisMethodInterceptor implements InstanceMethodsAroundInterceptor {

    @Override
    public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
                             Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable {
        AbstractSpan span = ContextManager.createExitSpan("Redis/" + method.getName(), "redis-server:6379");
        Tags.DB_TYPE.set(span, "redis");
        Tags.DB_STATEMENT.set(span, method.getName() + " " + Arrays.toString(allArguments));
    }

    @Override
    public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
                              Class<?>[] argumentsTypes, Object ret) throws Throwable {
        ContextManager.stopSpan();
        return ret;
    }

    @Override
    public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
                                      Class<?>[] argumentsTypes, Throwable t) {
        ContextManager.activeSpan().log(t);
    }
}

🧭 最佳实践总结

命名规范:为每个服务设置清晰的 service_name,便于在 UI 中识别。

采样策略:高流量系统应降低采样率(如 10%),避免存储压力过大。

敏感数据过滤:避免在 Span Tag 中记录密码、身份证号等敏感信息。

定期清理数据:配置 Elasticsearch 的 Index Lifecycle Management 自动删除旧数据。

结合日志:使用 TraceContext.traceId() 将链路 ID 注入日志,实现“追踪+日志”联动。

@GetMapping("/with-log")
public String withLog() {
    String traceId = TraceContext.traceId();
    logger.info("Processing request, traceId={}", traceId);
    return "Check logs with traceId: " + traceId;
}

权限控制:生产环境应启用 UI 登录认证,防止未授权访问。


❓ 常见问题解答

Q1: 启动时报错 “Address already in use”

确保 11800(OAP)、8080(UI)、8081(你的应用)等端口未被占用。

Q2: UI 中看不到服务

  • 检查 Agent 是否成功加载(控制台有日志)
  • 检查 backend_service 地址是否正确
  • 检查防火墙或网络策略

Q3: 如何监控非 Java 应用?

SkyWalking 支持 Node.js、Go、.NET、PHP 等,只需下载对应语言的 Agent 并按文档配置。

例如 Node.js:

npm install skywalking-backend-js
const sw = require('skywalking-backend-js');
sw.start({
  serviceName: 'my-nodejs-app',
  collectorAddress: 'http://localhost:12800'
});

Q4: 如何升级 SkyWalking?

备份配置文件 → 下载新版本 → 替换文件夹 → 重启服务。注意查看 Release Notes 是否有 Breaking Changes。


🚀 结语

恭喜你!🎉 你已经完成了从零部署 SkyWalking 到监控 Spring Boot 应用的全过程。整个过程不超过 5 分钟,却为你打开了分布式系统可观测性的大门。

SkyWalking 不仅仅是一个监控工具,它是你保障系统稳定性、优化性能瓶颈、快速定位故障的“超级武器”。无论是单体架构演进到微服务,还是 Kubernetes 环境下的云原生部署,SkyWalking 都能无缝适配,为你保驾护航。

探索更多:https://skywalking.apache.org/docs/

现在就开始在你的项目中集成 SkyWalking 吧!让每一次请求都清晰可见,让每一个异常都无所遁形。💻🔍📈


作者提示:技术更新迅速,本文基于 SkyWalking v9.7.0 + Spring Boot 3.1.5 编写,部分配置可能随版本变化,请以官方文档为准。

Happy Observing! 🎯📊🛠️


🙌 感谢你读到这里!
🔍 技术之路没有捷径,但每一次阅读、思考和实践,都在悄悄拉近你与目标的距离。
💡 如果本文对你有帮助,不妨 👍 点赞、📌 收藏、📤 分享 给更多需要的朋友!
💬 欢迎在评论区留下你的想法、疑问或建议,我会一一回复,我们一起交流、共同成长 🌿
🔔 关注我,不错过下一篇干货!我们下期再见!✨

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐