一、SkyWalking简介

1.1 什么是SkyWalking

SkyWalking是一款国产开源的应用性能监控(APM)系统,专为微服务、云原生和容器化架构设计。它于2015年由吴晟开源,2017年加入Apache孵化器,现已成为Apache顶级项目。SkyWalking提供分布式追踪、服务网格遥测分析、度量聚合和可视化一体化解决方案。

核心价值

  • 串联调用链路,快速定位问题

  • 理清微服务间依赖关系

  • 分析微服务接口性能

  • 追踪业务流程处理顺序

官方资源

1.2 链路追踪组件选型对比

特性 Zipkin Pinpoint SkyWalking CAT
实现方式 拦截请求,发送数据 Java探针,字节码增强 Java探针,字节码增强 代码埋点
接入方式 引入配置 javaagent字节码 javaagent字节码 代码侵入
协议 HTTP/MQ Thrift gRPC HTTP/TCP
颗粒度 接口级 方法级 方法级 代码级
全局调用统计 ×
JVM监控 × ×
OpenTracing × ×

性能对比(探针对吞吐量影响):

  • SkyWalking:影响最小

  • Zipkin:影响适中

  • Pinpoint:影响明显(500并发时吞吐量从1385降至774)

1.3 SkyWalking主要功能特性

  1. 多语言支持:Java、.NET Core、Node.JS等自动探针

  2. 轻量高效:无需大数据平台和大量服务器资源

  3. 模块化设计:UI、存储、集群管理有多种机制可选

  4. 完整监控方案:分布式追踪、度量聚合、可视化

  5. 告警功能:支持自定义告警规则和多种通知方式

  6. 服务网格支持:通过Service Mesh网络代理收集数据

二、SkyWalking整体架构

2.1 架构组成

text

┌─────────────┐    ┌─────────────┐    ┌─────────────┐
│    Agent    │────▶│     OAP     │────▶│  Storage   │
│   (探针)    │    │(分析平台)   │    │  (存储)    │
└─────────────┘    └─────────────┘    └─────────────┘
                           │
                    ┌──────┴──────┐
                    │     UI      │
                    │  (界面)     │
                    └─────────────┘

四大核心组件

2.1.1 Agent(探针)
  • 部署方式:与应用一起部署,通过-javaagent参数加载

  • 功能:收集应用性能数据,发送给OAP服务器

  • 技术:基于ByteBuddy字节码增强技术

2.1.2 OAP(Observability Analysis Platform)
  • 功能:接收Agent数据,进行分析、聚合、存储

  • 端口

    • 11800:接收Agent数据(gRPC)

    • 12800:提供查询接口(HTTP)

2.1.3 Storage(存储)
  • 支持存储:ElasticSearch、MySQL、TiDB、H2等

  • 推荐:生产环境建议使用ElasticSearch

2.1.4 UI(用户界面)
  • 默认UI:RocketBot UI(SkyWalking 7.0.0+)

  • 端口:默认8080

  • 功能:展示追踪数据、拓扑图、性能指标等

2.2 核心概念

  1. 服务(Service):提供相同功能的一组工作负载

  2. 服务实例(Service Instance):服务中的单个运行实例

  3. 端点(Endpoint):服务接收请求的路径(如HTTP URI)

  4. 追踪(Trace):一次请求的完整调用链

  5. 跨度(Span):Trace中的一个操作单元

三、SkyWalking环境搭建部署

3.1 下载与安装

下载地址:

bash

# SkyWalking APM
wget https://archive.apache.org/dist/skywalking/9.1.0/apache-skywalking-apm-9.1.0.tar.gz

# Java Agent(单独下载)
wget https://archive.apache.org/dist/skywalking/java-agent/8.11.0/apache-skywalking-java-agent-8.11.0.tgz
目录结构:

text

apache-skywalking-apm-bin/
├── bin/              # 启动脚本
│   ├── startup.sh    # 组合启动脚本
│   ├── oapService    # OAP启动脚本
│   └── webappService # UI启动脚本
├── config/           # 配置文件
│   ├── application.yml    # OAP配置
│   └── alarm-settings.yml # 告警配置
├── webapp/           # UI前端
├── oap-libs/         # OAP依赖库
└── agent/            # Agent探针
    ├── skywalking-agent.jar
    ├── config/
    ├── plugins/      # 必须插件
    └── optional-plugins/ # 可选插件

3.2 快速启动(使用H2存储)

1)修改配置

yaml

# config/application.yml
storage:
  selector: ${SW_STORAGE:h2}
2)启动服务

bash

# 启动OAP和UI
bin/startup.sh

# 查看日志
tail -f logs/skywalking-oap-server.log
tail -f logs/webapp.log
3)访问UI

text

http://localhost:8080

3.3 端口说明

服务 端口 说明
OAP Server 11800 接收Agent数据(gRPC)
OAP Server 12800 提供查询接口(HTTP)
Web UI 8080 用户界面(可修改)

四、SkyWalking快速开始

4.1 SkyWalking Agent追踪微服务

4.1.1 通过JAR包方式接入

Shell脚本启动方式

bash

#!/bin/sh
# SkyWalking Agent配置
export SW_AGENT_NAME=springboot-skywalking-demo
export SW_AGENT_COLLECTOR_BACKEND_SERVICES=127.0.0.1:11800
export SW_AGENT_SPAN_LIMIT=2000
export JAVA_AGENT="-javaagent:/path/to/skywalking-agent.jar"

java $JAVA_AGENT -jar your-application.jar

命令行参数方式

bash

java -javaagent:/path/to/skywalking-agent.jar \
     -DSW_AGENT_NAME=springboot-skywalking-demo \
     -DSW_AGENT_COLLECTOR_BACKEND_SERVICES=127.0.0.1:11800 \
     -jar your-application.jar
4.1.2 在IDEA中使用SkyWalking

配置JVM参数

text

-javaagent:D:\skywalking\agent\skywalking-agent.jar
-DSW_AGENT_NAME=springboot-skywalking-demo
-DSW_AGENT_COLLECTOR_BACKEND_SERVICES=192.168.65.206:11800
4.1.3 跨多个微服务追踪

注意事项

  1. 每个微服务都需要配置Agent

  2. Gateway服务需要特殊插件支持

Gateway插件配置

bash

# 拷贝Gateway插件到plugins目录
cp agent/optional-plugins/apm-spring-cloud-gateway-*.jar agent/plugins/
cp agent/optional-plugins/apm-spring-webflux-*.jar agent/plugins/

4.2 SkyWalking集成日志框架

4.2.1 集成Logback

添加依赖

xml

<dependency>
    <groupId>org.apache.skywalking</groupId>
    <artifactId>apm-toolkit-logback-1.x</artifactId>
    <version>8.11.0</version>
</dependency>

配置logback-spring.xml

xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
            <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
                <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%tid] [%thread] %-5level %logger{36} - %msg%n</Pattern>
            </layout>
        </encoder>
    </appender>
    
    <root level="INFO">
        <appender-ref ref="console"/>
    </root>
</configuration>

日志输出示例

text

2022-08-05 17:28:41.809 [TID:2fa2a77d1b244697aafb8a158ba5ad81.244.16596917217780005] [http-nio-8046] INFO ...
4.2.2 通过gRPC上报日志(v8.4.0+)

配置gRPC Appender

xml

<appender name="grpc-log" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender">
    <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
        <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
            <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%tid] [%thread] %-5level %logger{36} - %msg%n</Pattern>
        </layout>
    </encoder>
</appender>

4.3 SkyWalking告警通知

4.3.1 告警规则配置

配置文件config/alarm-settings.yml

示例规则

yaml

rules:
  service_resp_time_rule:
    metrics-name: service_resp_time
    op: ">"
    threshold: 1000
    period: 10
    count: 3
    silence-period: 5
    message: 服务响应时间超过1000ms

规则参数说明

  • metrics-name:度量名称(服务、实例、端点等)

  • op:操作符(>、<、=)

  • threshold:阈值

  • period:检查周期(分钟)

  • count:触发次数

  • silence-period:静默期

  • message:告警消息

4.3.2 WebHook回调

配置回调接口

yaml

webhooks:
  - http://localhost:8080/webhook

回调数据格式

json

[
  {
    "scopeId": 1,
    "scope": "SERVICE",
    "name": "serviceA",
    "id0": "c2VydmljZUE=",
    "id1": "",
    "ruleName": "service_resp_time_rule",
    "alarmMessage": "服务响应时间超过1000ms",
    "startTime": 1613913565462
  }
]

实现回调接口

java

@RestController
@RequestMapping("/webhook")
public class AlarmController {
    @PostMapping
    public void alarm(@RequestBody List<AlarmMessage> alarmMessages) {
        for (AlarmMessage alarmMessage : alarmMessages) {
            System.out.println(alarmMessage);
        }
    }
}
4.3.3 钉钉集成

配置示例

yaml

dingtalkHooks:
  textTemplate: |
    {
      "msgtype": "text",
      "text": {
        "content": "Apache SkyWalking Alarm: \n %s."
      }
    }
  webhooks:
    - url: https://oapi.dingtalk.com/robot/send?access_token=your_token
      secret: your_secret

4.4 SkyWalking持久化追踪数据

4.4.1 基于MySQL持久化

1. 修改配置

yaml

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}

2. 添加MySQL驱动

bash

# 将MySQL驱动包放到oap-libs目录
cp mysql-connector-java-8.0.xx.jar oap-libs/

3. 创建数据库

sql

CREATE DATABASE swtest CHARACTER SET utf8 COLLATE utf8_general_ci;
4.4.2 基于ElasticSearch持久化

1. 修改配置

yaml

storage:
  selector: ${SW_STORAGE:elasticsearch}
  elasticsearch:
    namespace: ${SW_NAMESPACE:""}
    clusterNodes: ${SW_STORAGE_ES_CLUSTER_NODES:localhost:9200}
    user: ${SW_ES_USER:""}
    password: ${SW_ES_PASSWORD:""}

2. 启动ElasticSearch

bash

# 单节点启动
bin/elasticsearch -d

# 查看状态
curl http://localhost:9200

4.5 自定义SkyWalking链路追踪

4.5.1 添加依赖

xml

<dependency>
    <groupId>org.apache.skywalking</groupId>
    <artifactId>apm-toolkit-trace</artifactId>
    <version>8.11.0</version>
</dependency>
4.5.2 获取TraceId

java

@RestController
public class UserController {
    @RequestMapping("/list")
    public List<User> list() {
        // 存储上下文信息
        TraceContext.putCorrelation("name", "fox");
        
        // 获取上下文信息
        Optional<String> name = TraceContext.getCorrelation("name");
        System.out.println("name = " + name.get());
        
        // 获取TraceId
        String traceId = TraceContext.traceId();
        System.out.println("traceId = " + traceId);
        
        return userService.list();
    }
}
4.5.3 使用@Trace注解

java

@Service
public class UserService {
    @Trace  // 将该方法加入追踪链路
    @Tag(key = "list", value = "returnedObj")
    public List<User> list() {
        return userMapper.list();
    }
    
    @Trace
    @Tags({
        @Tag(key = "param", value = "arg[0]"),
        @Tag(key = "user", value = "returnedObj")
    })
    public User getById(Integer id) {
        return userMapper.getById(id);
    }
}

@Tag注解说明

  • key:标签名称

  • value:标签值

    • arg[0]:方法第一个参数

    • arg[1]:方法第二个参数

    • returnedObj:返回值

4.6 SkyWalking集群部署

4.6.1 集群架构

text

          ┌─────────────┐
          │   Nginx     │
          │   (LB)      │
          └──────┬──────┘
          ┌──────┴──────┐
          │   Web UI    │
          │  集群       │
          └──────┬──────┘
    ┌────────────┼────────────┐
    │            │            │
┌───▼───┐  ┌───▼───┐  ┌───▼───┐
│ OAP1  │  │ OAP2  │  │ OAP3  │
└───┬───┘  └───┬───┘  └───┬───┘
    │           │           │
┌───▼───────────▼───────────▼───┐
│        ElasticSearch         │
│            集群              │
└───────────────────────────────┘
4.6.2 配置步骤

1. 修改OAP配置(使用Nacos注册中心)

yaml

cluster:
  selector: ${SW_CLUSTER:nacos}
  nacos:
    serviceName: ${SW_SERVICE_NAME:"SkyWalking_OAP_Cluster"}
    hostPort: ${SW_CLUSTER_NACOS_HOST_PORT:localhost:8848}
    namespace: ${SW_CLUSTER_NACOS_NAMESPACE:"public"}

2. 修改UI配置

yaml

# webapp/webapp.yml
server:
  port: 8080

spring:
  cloud:
    discovery:
      simple:
        instances:
          oap-service:
            - 192.168.1.101:12800
            - 192.168.1.102:12800
            - 192.168.1.103:12800

3. 启动顺序

  1. 启动Nacos集群

  2. 启动ElasticSearch集群

  3. 启动多个OAP实例

  4. 启动UI服务

  5. 配置Nginx负载均衡

五、常见问题与解决方案

5.1 Gateway追踪不显示

问题:Spring Cloud Gateway服务在追踪链路中不显示
解决方案

bash

# 拷贝Gateway相关插件
cp agent/optional-plugins/apm-spring-cloud-gateway-*.jar agent/plugins/
cp agent/optional-plugins/apm-spring-webflux-*.jar agent/plugins/

5.2 内存配置优化

调整JVM参数

bash

# 修改bin/oapService.sh
export JAVA_OPTS=" -Xms2g -Xmx2g -XX:+UseG1GC"

5.3 数据清理策略

配置数据保留时间

yaml

# config/application.yml
recordDataTTL: ${SW_RECORD_DATA_TTL:90}  # 记录数据保留90天
metricsDataTTL: ${SW_METRICS_DATA_TTL:90} # 指标数据保留90天

六、总结与最佳实践

6.1 部署建议

  1. 生产环境:使用ElasticSearch作为存储,配置集群模式

  2. 开发环境:可使用H2或MySQL,简化部署

  3. 监控范围:从核心业务服务开始,逐步扩大覆盖范围

6.2 性能优化

  1. 采样率调整:生产环境可适当降低采样率(如50%)

  2. 缓冲区配置:调整Agent缓冲区大小,平衡性能和数据完整性

  3. 网络优化:确保Agent与OAP之间的网络通畅

6.3 监控告警

  1. 关键指标:响应时间、错误率、吞吐量

  2. 告警分级:根据业务重要性设置不同级别的告警

  3. 通知渠道:结合邮件、钉钉、企业微信等多渠道通知

6.4 持续维护

  1. 版本升级:关注SkyWalking版本更新,及时升级

  2. 数据清理:定期清理过期数据,释放存储空间

  3. 性能监控:监控SkyWalking自身性能,确保监控系统稳定


七、学习资源推荐

  1. 官方文档https://skywalking.apache.org/docs/

  2. 中文社区https://skyapm.github.io/


本文基于SkyWalking v9.1.0版本编写,涵盖了从入门到生产部署的全流程。SkyWalking作为国产优秀的APM系统,在微服务监控领域表现出色,建议在实际项目中逐步应用,结合业务特点进行定制化配置。

Logo

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

更多推荐