一、SkyWalking 简介

Apache SkyWalking 是一个开源的应用性能监控(APM)和可观测性分析平台,专为分布式系统、微服务、云原生和基于容器的架构而设计。

核心特性

  • 分布式追踪:自动采集服务间调用链路,提供端到端的请求追踪
  • 性能指标监控:实时收集应用性能指标(吞吐量、响应时间、错误率等)
  • 服务拓扑分析:自动发现服务依赖关系,生成服务拓扑图
  • 告警机制:支持基于规则的智能告警
  • 多语言支持:Java、.NET Core、PHP、NodeJS、Golang、Python、Lua 等
  • 服务网格支持:与 Istio、Envoy 等服务网格集成

SkyWalking架构图

架构组件

SkyWalking 主要由以下核心组件构成:

  1. Agent(探针):部署在应用程序中,负责数据采集
  2. OAP Server(分析平台):接收、分析、聚合数据
  3. Storage(存储):支持 ElasticSearch、H2、MySQL 等多种存储方案
  4. UI(界面):提供可视化展示和分析能力

二、核心概念

1. Trace(调用链)

一次完整的分布式请求调用过程,由多个 Span 组成。每个 Trace 有唯一的 TraceId。

2. Span(跨度)

Trace 中的一个操作单元,代表一次方法调用、远程调用或数据库访问等。包含:

  • SpanId:当前 Span 的唯一标识
  • ParentSpanId:父 Span 的标识
  • 操作名称:如 HTTP 请求路径、数据库 SQL 等
  • 时间戳:开始和结束时间
  • Tags:键值对形式的元数据
  • Logs:事件日志

3. Service(服务)

提供一组相同功能的应用实例的集合。

4. Endpoint(端点)

服务中的具体路径或 URI,代表一个具体的业务功能入口。

三、Java Agent 使用

1. 下载 SkyWalking Agent

Apache SkyWalking 官网 下载对应版本的 Agent。

2. Agent 目录结构

skywalking-agent/
├── activations/          # 可选插件
├── config/              # 配置文件
│   └── agent.config
├── plugins/             # 核心插件
├── optional-plugins/    # 可选插件
├── bootstrap-plugins/   # 启动插件
└── skywalking-agent.jar # Agent 核心包

3. 应用接入

方式一:JVM 参数方式

在应用启动时添加 JVM 参数:

java -javaagent:/path/to/skywalking-agent.jar \
     -Dskywalking.agent.service_name=your-service-name \
     -Dskywalking.collector.backend_service=127.0.0.1:11800 \
     -jar your-application.jar

方式二:环境变量方式

export SW_AGENT_NAME=your-service-name
export SW_AGENT_COLLECTOR_BACKEND_SERVICES=127.0.0.1:11800
java -javaagent:/path/to/skywalking-agent.jar -jar your-application.jar

4. 核心配置说明

编辑 agent.config 文件:

# 服务名称(必填)
agent.service_name=${SW_AGENT_NAME:your-application}

# OAP Server 地址(必填)
collector.backend_service=${SW_AGENT_COLLECTOR_BACKEND_SERVICES:127.0.0.1:11800}

# 采样率(可选,默认为负数表示全量采集)
# agent.sample_n_per_3_secs=${SW_AGENT_SAMPLE:-1}

# 是否忽略特定后缀的 Trace
# agent.ignore_suffix=${SW_AGENT_IGNORE_SUFFIX:.jpg,.jpeg,.js,.css,.png,.bmp,.gif,.ico,.mp3,.mp4}

# 限制 Span 数量
# agent.span_limit_per_segment=${SW_AGENT_SPAN_LIMIT:300}

# 插件配置
# plugin.jdbc.trace_sql_parameters=${SW_JDBC_TRACE_SQL_PARAMETERS:false}

四、插件机制

1. 核心插件(默认加载)

SkyWalking 默认加载的插件包括:

  • HTTP 框架:Tomcat、Jetty、Spring MVC、Spring WebFlux
  • RPC 框架:Dubbo、gRPC、Motan
  • 数据库:MySQL、Oracle、PostgreSQL、MongoDB、Redis
  • 消息队列:Kafka、RabbitMQ、RocketMQ、ActiveMQ
  • 缓存:Jedis、Lettuce、Redisson
  • 日志框架:Logback、Log4j、Log4j2

2. 可选插件

位于 optional-plugins/ 目录,需要手动复制到 plugins/ 目录才会生效:

# 启用 Spring Cloud Gateway 插件
cp optional-plugins/apm-spring-cloud-gateway-*.jar plugins/

# 启用 trace 日志上下文插件
cp optional-plugins/apm-trace-ignore-plugin-*.jar plugins/

3. 自定义插件开发

如需监控自定义组件,可以开发 SkyWalking 插件:

// 1. 定义增强点
public class MyComponentInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
    @Override
    protected ClassMatch enhanceClass() {
        return NameMatch.byName("com.example.MyComponent");
    }

    @Override
    public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
        return new InstanceMethodsInterceptPoint[]{
            new InstanceMethodsInterceptPoint() {
                @Override
                public ElementMatcher<MethodDescription> getMethodsMatcher() {
                    return named("execute");
                }

                @Override
                public String getMethodsInterceptor() {
                    return "com.example.MyComponentInterceptor";
                }

                @Override
                public boolean isOverrideArgs() {
                    return false;
                }
            }
        };
    }
}

// 2. 实现拦截器
public class MyComponentInterceptor implements InstanceMethodsAroundInterceptor {
    @Override
    public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
                            Class<?>[] argumentsTypes, MethodInterceptResult result) {
        // 创建 Span
        AbstractSpan span = ContextManager.createLocalSpan("MyComponent/execute");
        span.setComponent(ComponentsDefine.CUSTOM);
        Tags.LOGIC_ENDPOINT.set(span, true);
    }

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

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

五、实践要点

1. 采样策略

根据业务场景选择合适的采样率:

# 全量采集(生产环境慎用)
agent.sample_n_per_3_secs=-1

# 每 3 秒采样 1000 条
agent.sample_n_per_3_secs=1000

# 每 3 秒采样 100 条(适合高并发场景)
agent.sample_n_per_3_secs=100

2. 性能优化

限制 Span 数量:避免超长调用链导致内存溢出

agent.span_limit_per_segment=300

忽略静态资源:减少无效 Trace

agent.ignore_suffix=.jpg,.jpeg,.js,.css,.png,.bmp,.gif,.ico

关闭 SQL 参数追踪:降低数据量(生产环境推荐)

plugin.jdbc.trace_sql_parameters=false

3. 常见问题

Q1:Agent 对应用性能影响有多大?

A:经过优化后,性能损耗通常在 5% 以内。主要影响因素:

  • 采样率设置
  • 插件数量
  • 网络传输开销

Q2:如何排查 Agent 未生效?

A:检查以下几点:

  1. JVM 参数是否正确配置
  2. agent.config 配置是否正确
  3. OAP Server 是否可访问
  4. 查看应用日志中的 SkyWalking 启动信息
  5. 检查 logs/skywalking-api.log

Q3:如何在容器化环境使用?

A:Dockerfile 示例:

FROM openjdk:8-jre

# 复制 Agent
COPY skywalking-agent /skywalking-agent

# 复制应用
COPY app.jar /app.jar

# 设置环境变量
ENV SW_AGENT_NAME=my-service
ENV SW_AGENT_COLLECTOR_BACKEND_SERVICES=oap-server:11800

# 启动应用
ENTRYPOINT ["java", "-javaagent:/skywalking-agent/skywalking-agent.jar", "-jar", "/app.jar"]

六、总结

Apache SkyWalking 作为一款优秀的 APM 工具,具有以下优势:

零侵入:通过 Java Agent 技术,无需修改代码
轻量级:性能损耗低,适合生产环境
功能全面:覆盖追踪、度量、日志等多维度监控
扩展性强:插件机制支持自定义扩展
社区活跃:Apache 顶级项目,持续更新维护

通过合理配置和使用 SkyWalking,可以有效提升分布式系统的可观测性,快速定位性能瓶颈和故障根因。

参考资料