前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >054. SkyWalking

054. SkyWalking

作者头像
山海散人
发布2021-03-03 10:44:01
1.8K0
发布2021-03-03 10:44:01
举报
文章被收录于专栏:山海散人技术山海散人技术

1. APM系统


1.1. APM系统概述
  • APM (Application Performance Management) 即应用性能管理系统,是对企业系统即时监控以实现对应用程序性能管理和故障管理的系统化的解决方案。应用性能管理,主要指对企业的关键业务应用进行监测、优化,提高企业应用的可靠性和质量,保证用户得到良好的服务,降低 IT 总拥有成本。
  • APM系统是可以帮助理解系统行为、用于分析性能问题的工具,以便发生故障的时候,能够快速定位和解决问题。
1.2. 分布式链路追踪
  • 随着分布式系统和微服务架构的出现,一次用户的请求会经过多个系统,不同服务之间的调用关系十分复杂,任何一个系统出错都可能影响整个请求的处理结果。以往的监控系统往往只能知道单个系统的健康状况、一次请求的成功失败,无法快速定位失败的根本原因。
  • 除此之外,复杂的分布式系统也面临这下面这些问题:
    • 性能分析:一个服务依赖很多服务,被依赖的服务也依赖了其他服务。如果某个接口耗时突然变长了,那未必是直接调用的下游服务慢了,也可能是下游的下游慢了造成的,如何快速定位耗时变长的根本原因呢?
    • 链路梳理:需求迭代很快,系统之间调用关系变化频繁,靠人工很难梳理清楚系统链路拓扑(系统之间的调用关系)。
  • 为了解决这些问题,Google 2010 年发布文章 Dapper,大规模分布式系统的跟踪系统,之后各个互联网公司都参照 Dapper 的思想推出了自己的分布式链路跟踪系统,而这些系统就是分布式系统下的 APM 系统。
1.3. OpenTracing
1.4. 主流开源APM产品

CAT

Zipkin

Apache SkyWalking

调用链可视化

聚合报表

非常丰富

较丰富

服务依赖图

简单

简单

埋点方式

侵入

侵入

非侵入,运行期字节码增强

VM 指标监控

告警支持

多语言支持

Java、C/C++、Node.js、Python、Go

丰富

Java、LUA、Python、.NET、Node.js、PHP、GO2Sky

存储机制

MySQL(报表)、本地文件、HDFS(调用链)

可选 inMemory、MySQL、ES(生产)、Cassandra(生产)

ES、MySQL、Sharding Sphere、TiDB、H2

社区支持

主要在国内,点评/美团

文档丰富,国外主流

Apache 支持,国内社区好

国内案例

点评、携程、陆金所、拍拍贷等

京东、阿里定制不开源等

华为、小米、当当、微众银行等

源头

eBay CAL

Google Dapper

Google Dapper

同类产品

暂无

Uber Jaeger、Spring Cloud Sleuth

Naver Pinpoint

出现年份

2011

2012

2015

Github Stars

14.1k

13.3k

14.3k

亮点

企业生产级,报表丰富

社区生态好

非侵入,Apache 背书

不足

用户体验一般,社区一般

APM 报表能力弱

时间不长,文档一般,仅限中文社区

2. SkyWalking


2.1. 概述
  • SkyWalking:一个开源的可观测平台, 用于从服务和云原生基础设施收集, 分析, 聚合及可视化数据。
  • SkyWalking 提供了一种简便的方式来清晰地观测分布式系统, 甚至横跨多个云平台。SkyWalking 更是一个现代化的应用程序性能监控(Application Performance Monitoring)系统, 尤其专为云原生、基于容器的分布式系统设计。
2.2. 特点
  • 多语言自动探针,Java, C# , Node.js , Go , PHP 以及 Nginx LUA(包括 Python 和 C++ 调用的 SDK 捐献)。
  • 多种监控手段,语言探针和 service mesh。
  • 轻量高效。不需要额外搭建大数据平台。
  • 模块化架构。UI、存储、集群管理多种机制可选。
  • 支持告警。
  • 优秀的可视化解决方案。
2.3. 核心概念
  • 服务(Service):表示对请求提供相同行为的一组工作负载。在使用打点代理或 SDK 的时候,你可以定义服务的名字。SkyWalking 还可以使用在 Istio 等平台中定义的名称。
  • 服务实例(Service Instance):上述的一组工作负载中的每一个工作负载称为一个实例。就像 Kubernetes 中的 pods 一样,服务实例未必就是操作系统上的一个进程。但当你在使用打点代理的时候,一个服务实例实际就是操作系统上的一个真实进程。
  • 端点(Endpoint):对于特定服务所接收的请求路径,如 HTTP 的 URI 路径和 gRPC 服务的类名 + 方法签名。
2.4. 架构

SkyWalking 逻辑上分为四部分:探针、平台后端、存储和用户界面。

image-20200817174617995
image-20200817174617995
  • 探针:基于不同的来源可能是不一样的,但作用都是收集数据,将数据格式化为 SkyWalking 适用的格式。
  • 平台后端:支持数据聚合,数据分析以及驱动数据流从探针到用户界面的流程。分析包括 SkyWalking 原生追踪和性能指标以及第三方来源,包括 Istio 及 Envoy telemetry、Zipkin 追踪格式化等。 你甚至可以使用 Observability Analysis Language 对原生度量指标用于扩展度量的计量系统 自定义聚合分析。
  • 存储:通过开放的插件话的接口存放 SkyWalking 数据。你可以选择一个既有的存储系统,如 ElasticSearch、H2 或 MySQL 集群(Sharding-Sphere 管理),也可以选择自己实现一个存储系统。
  • UI:一个基于接口高度定制化的 Web 系统,用户可以可视化查看和管理 SkyWalking 数据。

3. 环境搭建


3.1. 单机环境
3.2. 集群环境
  • 详细文档查看《SkyWalking 集群环境搭建》。
3.3. Docker 安装单机环境

4. agent 使用


4.1. IDEA 使用
  • idea 运行配置中配置以下参数。
image-20200818173138343
image-20200818173138343
  • -javaagent 是 agent jar 的位置,该 jar 包可在 skywalking 安装包中找到。
  • SW_AGENT_NAME 是该服务在 skywalking 中的服务名称。
  • SW_AGENT_COLLECTOR_BACKEND_SERVICES 是 skywalking 服务的采集数据端口。
4.2. JAR 命令启动
代码语言:javascript
复制
java -javaagent:E:\Workspaces\LearnWorkspace\SkyWalking示例\skywalking\apache-skywalking-apm-bin-es7\agent\skywalking-agent.jar -Dskywalking.agent.service_name=skywalking-user -Dskywalking.collector.backend_service=127.0.0.1:11800 -jar user-1.0.0-SNAPSHOT.jar

5. 配置覆盖


  • 默认情况下,SkyWalking为agent提供了agent.config配置文件。
  • 配置覆盖意味着用户可以通过系统属性或 agent 选项覆盖配置文件中的配置。
5.1. 系统属性
5.2. agent 选项
5.3. 系统环境变量
  • 修改配置文件中的值。
代码语言:javascript
复制
agent.service_name=${SW_AGENT_NAME:Your_ApplicationName}
collector.backend_service=${SW_AGENT_COLLECTOR_BACKEND_SERVICES:127.0.0.1:11800}
logging.level=${SW_LOGGING_LEVEL:INFO}
  • 如果 SW_AGENT_NAME 环境变量在你的操作系统中已存在,并且它的值为 skywalking-demo ,那么这里的 agent.service_name 的值将会被覆写为 skywalking-demo , 否则, 它将会被设置成 Your_ApplicationName
  • 另外,占位符嵌套也是支持的,比如 {SW_AGENT_NAME:{ANOTHER_AGENT_NAME:Your_ApplicationName}}。 在这种情况下,如果 SW_AGENT_NAME 环境变量不存在,但是 ANOTHER_AGENT_NAME 环境变量存在,并且它的值为 skywalking-demo , 那么这里的 agent.service_name 的值将会被覆写为skywalking-agent-demo , 否则, 它将会被设置成 Your_ApplicationName 。
5.4. 覆盖优先级
  • 探针配置 > 系统配置 > 系统环境变量 > 配置文件中的值。

6. 获取追踪ID


7. 过滤指定端点


8. 打印日志信息


9. 告警功能


9.1. 告警功能简介
9.2. 告警测试代码
9.3. 告警处理 webhook

告警的消息通过 HTTP 请求进行发送,请求方法是 POST,Content-Type 是 application/json,JSON 格式基于 List<org.apache.skywalking.oap.server.core.alarm.AlarmMessage。

9.4. 部署测试

10. java agent 的原理


10.1. java agent 是什么?
  • Java agent 是 java 命令的一个参数。参数 javaagent 可以用于指定一个 jar 包。
    • 这个 jar 包的 MANIFEST.MF 文件必须指定 Premain-Class 项。
    • Premain-Class 指定的那个类必须实现 premain() 方法。
  • 当Java 虚拟机启动时,在执行 main 函数之前,JVM 会先运行 -javaagent 所指定 jar 包内 Premain-Class 这个类的 premain 方法 。
10.2. 如何使用 java agent?
  • 定义一个 MANIFEST.MF 文件,必须包含 Premain-Class 选项,通常也会加入Can-Redefifine-Classes 和 Can-Retransform-Classes 选项。
  • 创建一个Premain-Class 指定的类,类中包含 premain 方法,方法逻辑由用户自己确定。
  • 将 premain 的类和 MANIFEST.MF 文件打成 jar 包。
  • 使用参数 -javaagent: jar 包路径启动要代理的方法。
10.3. 搭建 java agent 工程
10.3.1. 新建 PreMainAgent 类
代码语言:javascript
复制
public class PreMainAgent {

    /**
     * 在这个 premain 函数中,开发者可以进行对类的各种操作。
     * 1、agentArgs 是 premain 函数得到的程序参数,随同 “– javaagent”一起传入。与 main 函数不同的是,
     * 这个参数是一个字符串而不是一个字符串数组,如果程序参数有多个,程序将自行解析这个字符串。
     *
     * 2、Inst 是一个 java.lang.instrument.Instrumentation 的实例,由 JVM 自动传入。*
     * java.lang.instrument.Instrumentation 是 instrument 包中定义的一个接口,也是这个包的核心部分,
     * 集中了其中几乎所有的功能方法,例如类定义的转换和操作等等。
     */
    public static void premain(String agentArgs, Instrumentation inst) {
        System.out.println("premain 方法执行 1");
        System.out.println(agentArgs);
    }

    /**
     * 如果不存在 premain(String agentArgs, Instrumentation inst)
     * 则会执行 premain(String agentArgs)
     */
    public static void premain(String agentArgs) {
        System.out.println("premain 方法执行 2");
        System.out.println(agentArgs);
    }

}
  • 类中提供两个静态方法,方法名均为premain,不能拼错。
10.3.2. pom 添加打包插件
代码语言:javascript
复制
<build>
    <plugins>
        <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <configuration>
                <appendAssemblyId>false</appendAssemblyId>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
                <archive>
                    <!--自动添加META-INF/MANIFEST.MF -->
                    <manifest>
                        <addClasspath>true</addClasspath>
                    </manifest>
                    <manifestEntries>
                        <Premain-Class>com.zp.skywalking.javaagentdemo.PreMainAgent</Premain-Class>
                        <Agent-Class>com.zp.skywalking.javaagentdemo.PreMainAgent</Agent-Class>
                        <Can-Redefine-Classes>true</Can-Redefine-Classes>
                        <Can-Retransform-Classes>true</Can-Retransform-Classes>
                    </manifestEntries>
                </archive>
            </configuration>
            <executions>
                <execution>
                    <id>make-assembly</id>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
  • 该插件会在自动生成META-INF/MANIFEST.MF文件时,帮我们添加agent相关的配置信息。
10.3.3. 打包
  • 使用 maven 的package 命令进行打包。
10.3.4. 使用
10.4. 示例:统计方法的调用时间
10.4.1. Byte Buddy
  • Skywalking 中对每个调用的时长都进行了统计,这一小节中我们会使用 ByteBuddy 和 Java agent 技术来统计方法的调用时长。
  • Byte Buddy 是开源的、基于 Apache 2.0 许可证的库,它致力于解决字节码操作和 instrumentation API 的复杂性。Byte Buddy 所声称的目标是将显式的字节码操作隐藏在一个类型安全的领域特定语言背后。通过使用 Byte Buddy,任何熟悉 Java 编程语言的人都有望非常容易地进行字节码操作。ByteBuddy 提供了额外的 API 来生成 Java agent,可以轻松的增强我们已有的代码。
10.4.2. 添加依赖
代码语言:javascript
复制
<dependency>
    <groupId>net.bytebuddy</groupId>
    <artifactId>byte-buddy</artifactId>
    <version>1.10.14</version>
</dependency>
<dependency>
    <groupId>net.bytebuddy</groupId>
    <artifactId>byte-buddy-agent</artifactId>
    <version>1.10.14</version>
    <scope>test</scope>
</dependency>
10.4.3. PreMainAgent 代码
代码语言:javascript
复制
import net.bytebuddy.agent.builder.AgentBuilder;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.matcher.ElementMatchers;
import net.bytebuddy.utility.JavaModule;

import java.lang.instrument.Instrumentation;

public class PreMainAgent {

    public static void premain(String agentArgs, Instrumentation inst) {
        //创建一个转换器,转换器可以修改类的实现
        //ByteBuddy对java agent提供了转换器的实现,直接使用即可 AgentBuilder.Transformer transformer = new AgentBuil
        AgentBuilder.Transformer transformer = new AgentBuilder.Transformer() {
            @Override
            public DynamicType.Builder<?> transform(DynamicType.Builder<?> builder, TypeDescription typeDescription, ClassLoader classLoader, JavaModule javaModule) {
                return builder
                        // 拦截任意方法
                        .method(ElementMatchers.<MethodDescription>any())
                        // 拦截到的方法委托给 TimeInterceptor
                        .intercept(MethodDelegation.to(MyInterceptor.class));
            }
        };

        new AgentBuilder // Byte Buddy 专门有个 AgentBuilder 来处理 Java Agent 场景
                .Default()
                // 根据包名前缀拦截类
                .type(ElementMatchers.nameStartsWith("com.myspace.server"))
                // 拦截到的类由 transformer 处理
                .transform(transformer)
                .installOn(inst);
    }

}
  • 先生成一个转换器,ByteBuddy 提供了java agent 专用的转换器。通过实现 Transformer 接口利用 builder 对象来创建一个转换器。转换器可以配置拦截方法的格式,比如用名称,本例中拦截所有方法,并定义一个拦截器类 MyInterceptor。
  • 创建完拦截器之后可以通过 Byte Buddy 的 AgentBuilder 建造者来构建一个 agent 对象。AgentBuilder 可以对指定的包名前缀来生效,同时需要指定转换器对象。
10.4.4. MyInterceptor
代码语言:javascript
复制
import net.bytebuddy.implementation.bind.annotation.Origin;
import net.bytebuddy.implementation.bind.annotation.RuntimeType;
import net.bytebuddy.implementation.bind.annotation.SuperCall;

import java.lang.reflect.Method;
import java.util.concurrent.Callable;

public class MyInterceptor {

    @RuntimeType
    public static Object intercept(@Origin Method method, @SuperCall Callable<?> callable) throws Exception {
        long start = System.currentTimeMillis();
        try {
            // 执行原方法
            return callable.call();
        } finally {
            // 打印调用时长
            System.out.println(method.getName() + ":" + (System.currentTimeMillis() - start) + "ms");
        }
    }

}
  • MyInterceptor 就是一个拦截器的实现,统计的调用的时长。参数中的 method 是反射出的方法对象,而 callable 就是调用对象,可以通过 callable.call() 方法来执行原方法。
10.4.5. 重新打包
10.4.6. 修改主程序代码,将 Main 类放到 com.myspace.server 包下。
代码语言:javascript
复制
public class Main {
    public static void main(String[] args) throws InterruptedException {
        Thread.sleep(1000);
        System.out.println("Hello World!");
    }
}
10.4.7. 运行这个 Main 类
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/09/07 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. APM系统
    • 1.1. APM系统概述
      • 1.2. 分布式链路追踪
        • 1.3. OpenTracing
          • 1.4. 主流开源APM产品
          • 2. SkyWalking
            • 2.1. 概述
              • 2.2. 特点
                • 2.3. 核心概念
                  • 2.4. 架构
                  • 3. 环境搭建
                    • 3.1. 单机环境
                      • 3.2. 集群环境
                        • 3.3. Docker 安装单机环境
                        • 4. agent 使用
                          • 4.1. IDEA 使用
                            • 4.2. JAR 命令启动
                            • 5. 配置覆盖
                              • 5.1. 系统属性
                                • 5.2. agent 选项
                                  • 5.3. 系统环境变量
                                    • 5.4. 覆盖优先级
                                    • 6. 获取追踪ID
                                    • 7. 过滤指定端点
                                    • 8. 打印日志信息
                                    • 9. 告警功能
                                      • 9.1. 告警功能简介
                                        • 9.2. 告警测试代码
                                          • 9.3. 告警处理 webhook
                                            • 9.4. 部署测试
                                            • 10. java agent 的原理
                                              • 10.1. java agent 是什么?
                                                • 10.2. 如何使用 java agent?
                                                  • 10.3. 搭建 java agent 工程
                                                    • 10.3.1. 新建 PreMainAgent 类
                                                    • 10.3.2. pom 添加打包插件
                                                    • 10.3.3. 打包
                                                    • 10.3.4. 使用
                                                  • 10.4. 示例:统计方法的调用时间
                                                    • 10.4.1. Byte Buddy
                                                    • 10.4.2. 添加依赖
                                                    • 10.4.3. PreMainAgent 代码
                                                    • 10.4.4. MyInterceptor
                                                    • 10.4.5. 重新打包
                                                    • 10.4.6. 修改主程序代码,将 Main 类放到 com.myspace.server 包下。
                                                    • 10.4.7. 运行这个 Main 类
                                                相关产品与服务
                                                腾讯云 BI
                                                腾讯云 BI(Business Intelligence,BI)提供从数据源接入、数据建模到数据可视化分析全流程的BI能力,帮助经营者快速获取决策数据依据。系统采用敏捷自助式设计,使用者仅需通过简单拖拽即可完成原本复杂的报表开发过程,并支持报表的分享、推送等企业协作场景。
                                                领券
                                                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档