开篇词:从剖析 SkyWalking 源码到吃透 APM 核心知识

你好,我是你的 SkyWalking 老师徐郡明,网名吴小胖,你也可以叫我胖哥。进入互联网行业工作多年,主要从事基础组件开发相关的工作,曾任搜狗资深技术专家,目前就职于某知名短视频互联网公司,主要负责开发、运维全公司的 APM 系统,深入研究多个开源中间件,对 APM 系统有十分深入的研究。曾牵头改造过多个开源产品,在架构设计方面经验丰富。热衷于技术分享,著有畅销书《Apache Kafka 源码剖析》《MyBatis 技术内幕》《etcd 技术内幕》《OpenTSDB  技术内幕》《Promethus 技术秘籍》等。

为什么你必须精通一款 APM

最近十年,互联网经历了移动互联网的爆发,大数据的飞速发展,云计算、IoT 以及工业 4.0 的百花齐放,互联网产品之间的竞争愈演愈烈的同时,支撑这些产品的后端服务架构也进行了一次次革新,从单层架构到多层架构,从单机服务到微服务架构,再到现在兴起的中台架构。混合、复杂的 IT 环境使故障定位、数据统计、性能优化等问题越来越复杂,运维人员与开发人员压力持续增大。

于是 APM 系统(Application Performance Management,即应用性能管理)应运而生,它是 IT 运维管理市场最大的子领域之一,可以很好地解决这一难题。

  • 最早期的 APM 以监控 CPU 使用率、I/O、内存资源、网速等网络基础设施为主;

  • 随着中间件技术的不断发展,APM 也开始监控缓存、数据库、MQ 等各种基础组件的性能;

  • 为了快速响应业务变化,微服务兴起之后,系统功能被模块化,部署方式以服务集群为主,运维管理的复杂度也随之出现爆炸性的增长,需要一些手段了解系统行为、分析系统的性能来及时发现或定位问题、预判系统负载能力等,于是,APM 又肩负起了监控整个微服务架构下所有服务性能的重担。

所以,精通至少一款 APM 系统也已经是运维工程师、开发工程师以及架构师的一项必备技能。

APM 那么多,学哪个呢?

答案当然是:企业用哪个就学哪个!那么,企业用哪个呢?

几乎所有的互联网公司都有 APM 系统,力求及时发现故障,并为优化系统提供性能数据支持。

  • 有的会直接用开源产品,国内比较常用的是美团开源的 CAT、Twitter 开源的 Zipkin、韩国开源的 Pinpoint 和本专栏要讲的 SkyWalking 等;

  • 有的则选择基于开源产品进行改造和自研以满足企业需求;

  • 还有的会选购一些商业化的 APM 产品;

  • 当然一线大厂多数会自研,如淘宝鹰眼、Google Dapper 等。

以上提到的都是经过市场验证的优秀的 APM,但如果要选择一款学透的话,我建议你选 SkyWalking。为什么呢?

  • 第一,它是一个基于 OpenTracing 规范,专门为微服务架构以及云原生架构而设计的,2019 年从 Apache 基金会孵化器毕业成为顶级项目;

  • 第二,你青睐的大厂很多都使用 SkyWalking ,包括腾讯、阿里云、华为、滴滴、中国电信、中国联通等;

  • 第三,相比于其他几个,SkyWalking 没有企业束缚,社区活跃,增长势头强劲;

  • 第四,它是国人开源的,中文文档齐全,学起来没有语言障碍;

  • 第五,SkyWalking 支持 Java、.Net、Node.js 等多款语言的探针,还提供了多种开源框架的插件,例如 Dubbo、gRPC、SOFARPC 等;

  • 第六,有很多开发者持续不断地向社区提供更多插件以支持更多组件无缝接入 SkyWalking;

  • ……

学到什么程度?怎么学?

如果你想进入的是中小型企业,那你至少要学会 SkyWalking 如何使用。如果你想进入有自研 APM 的大中型企业那你必须剖析 SkyWalking 最顶层的架构设计和核心实现原理才行:只有深入代码,才能学以致用。

如果真的搜过学习资料,你一定发现了网络上很多关于 SkyWalking 的博客和文章都有这些小问题。

  • 第一,只讲 SkyWalking 的概述,教你 SkyWalking 一些简单的使用方式或是简单比较 SkyWalking 与其他 APM 系统。如果你想学如何用好 SkyWalking,显然这种浅尝辄止的介绍是不够的。

  • 第二,没有展开顶层的设计,只是简单介绍了部分代码的实现含义,让你一知半解,根本无法解决实际问题。

  • 第三,不少文章对应的 SkyWalking 版本略微陈旧,只能作为参考,直接拿来用的话会出现一些意想不到的问题。

当然,还有其他学习方法,常见的有以下两种:

  • 第一,找身边前辈给你介绍一下系统的原理和架构。那么,你的学习效果便会受限于前辈讲解时的状态,以及你当时的学习状态,能吸收多少,全看缘分。

  • 第二,阅读源码。既然能够拿到全部的代码,直接阅读代码就可以了解系统的工作原理了。没错,但如果你尝试过就会知道,这是一个非常艰辛的过程。

  1. 很多遗留系统和开源系统,虽然功能强大,但文档不全、需要搭建外部依赖环境等,这些对新手来说都是非常不友好的,在入手把玩一个开源项目的时候,有 90% 的人在源码环境搭建过程中打了退堂鼓。

  2. 另外,自己看源码需要搜集很多资料,而很多资料是过时或错误的,这非常干扰你的学习、浪费你的时间。

  3. 最要命的是,因为视野有限,在自己从头开始阅读源码时,经常会迷失在代码迷宫中,出现“不识庐山真面目,只缘身在此山中”的情况。这会导致你花了很大力气阅读源码,付出了大量时间去 Debug 源码,却在关上 IDEA 之后,依然觉得雾里看花。

为什么要跟着我学?

学习本专栏的过程就像是在修习武侠小说中的一门掌法。课程中的每一个知识点都像是一个招式;整个分析 SkyWalking 实现的过程,就是将所有招式整合起来,形成完整掌法的过程。我会根据自己丰富的开源项目学习经验:

  • 从基础知识开始,通过丰富的 Demo 演示,手把手教你 SkyWalking 的落地实现和技巧;

  • 作为路人,带你自底向上剖析优秀源码,深入理解 SkyWalking 设计理念、工作原理及核心实现;

  • 通过实例,带你感受利用 SkyWalking 的设计思想解决工作中的实际问题,提升你的 Coding 能力。

相信通过本课程,除了彻底搞懂 SkyWalking,你还会:

  • 获得剖析其他开源项目代码的能力;

  • 获得在实际工作中遇到类似问题沉着应对的能力,这比学会任何一个知识点都要重要;

  • 获得面试优势,正如前面看到的那样,Skywalking 应用非常广泛,探讨 SkyWalking 的实现原理也可能会成为你和面试官的共同话题;

  • 触类旁通,Skywalking 实现了 OpenTracing 规范,理解 SkyWalking 的原理之后,在使用或是理解其他 APM 系统会非常轻松。

寻找更优秀的自己

架构设计以及编程是需要想象力和创造力的,但是有意义的想象和创造不是凭空来的,而是需要站在巨人的肩膀上。多多研究开源产品或前辈给出的解决方案和最佳实践,才会在实际工作中迸发出更多更好的“灵感”。欢迎订阅我的专栏,让我们一起探寻更优秀的自己,下节课见!


第01讲:同九义,为何 SkyWalking 一枝独秀?

随着互联网时代的发展,很多企业为了快速响应业务的变化,开始使用微服务架构。微服务架构的系统常常被切分为多个独立的子系统并以集群的方式部署在数十甚至成百上千的机器上。

虽然微服务架构带来更大的灵活性、更高的开发效率等等一系列好处,但是同样也面临着很多问题。为掌握系统的运行状态,确保系统正常对外提供服务,需要一些手段去监控系统,以了解系统行为,分析系统的性能,或在系统出现故障时,能发现问题、记录问题并发出告警,从而帮助运维人员发现问题、定位问题。也可以根据监控数据发现系统瓶颈,提前感知故障,预判系统负载能力等。

这里简单以一个电商网站的单机架构与微服务架构进行对比,说明微服务架构中需要解决的一些问题。

图中展示了单机架构下的电商平台,用户使用浏览器发起请求访问电商系统,电商系统会直接从后端的数据库存储中查询相应的用户数据、订单数据、商品信息,以及库存数据等进行展示。当系统出现性能下降、异常信息的问题时,运维人员可以直接去电商系统中查看相应的日志或是系统监控,就基本可以定位到问题。

下图展示了现实中微服务架构下的电商系统,整个电商系统被拆分成了很多子服务,每个子服务都是以集群的方式对外提供服务。当用户通过浏览器/手机 App 浏览商城的时候,请求会首先到达接入层 API 集群中的一个实例,该实例会通过 RPC 请求库存服务、商品服务、订单服务、用户服务,查询底层的存储,获取相应的数据,最终形成完整的响应结果返回给用户。

![在这里插入图片描述](https://img-blog.csdnimg.cn/ef76bb96161c4a68867554a37d2429cc.png#pic_center)

群无法支撑现在的访问量时,整个电商系统对外表现的性能就会下降,而用户请求涉及的服务和服务实例比较多,要查找到这个问题就需要浏览多个服务和机器的日志,步骤非常繁琐,所以说微服务架构下的问题定位变得比较困难。

在定位到这个问题之后,我们可能考虑要给商品服务集群进行扩容,计算扩容多少台机器、新增部署多少个实例,都是需要相应的数据做支撑的,而不是凭开发和运维人员的直觉。为了解决微服务架构系统面临的上述挑战,APM 系统应运而生。

Logging&Metrics&Tracing

微服务系统的监控主要包含以下三个方面:

  • Logging 就是记录系统行为的离散事件,例如,服务在处理某个请求时打印的错误日志,我们可以将这些日志信息记录到 ElasticSearch 或是其他存储中,然后通过 Kibana 或是其他工具来分析这些日志了解服务的行为和状态。大多数情况下,日志记录的数据很分散,并且相互独立,比如错误日志、请求处理过程中关键步骤的日志等等。

  • Metrics 是系统在一段时间内某一方面的某个度量,例如,电商系统在一分钟内的请求次数。我们常见的监控系统中记录的数据都属于这个范畴,例如 Promethus、Open-Falcon 等,这些监控系统最终给运维人员展示的是一张张二维的折线图。Metrics 是可以聚合的,例如,为电商系统中每个 HTTP 接口添加一个计数器,计算每个接口的 QPS,之后我们就可以通过简单的加和计算得到系统的总负载情况。

  • Tracing 即我们常说的分布式链路追踪。在微服务架构系统中一个请求会经过很多服务处理,调用链路会非常长,要确定中间哪个服务出现异常是非常麻烦的一件事。通过分布式链路追踪,运维人员就可以构建一个请求的视图,这个视图上展示了一个请求从进入系统开始到返回响应的整个流程。这样,就可以从中了解到所有服务的异常情况、网络调用,以及系统的性能瓶颈等。

另外,还能够迅速应对需求变化也是微服务架构的特点之一,这就会导致各个服务之间的调用关系发生频繁的变化,人工维护这种关系成本很高,通过分布式链路追踪即可掌握系统中各个服务的调用关系。

谷歌在 2010 年 4 月发表了一篇论文《Dapper, a Large-Scale Distributed Systems Tracing Infrastructure》介绍了分布式追踪的概念,之后很多互联网公司都开始根据这篇论文打造自己的分布式链路追踪系统。前面提到的 APM 系统的核心技术就是分布式链路追踪。下面通过官方的一个示例简单介绍说明什么是 Tracing。

在一个分布式系统中,追踪一个事务或者调用流一般如上图所示。虽然这种图对于看清各组件的组合关系很有用,但是,它不能很好显示组件的调用时间,是串行调用还是并行调用,如果展现更复杂的调用关系,会更加复杂,甚至无法画出这样的图。

一种更有效的展现方式就是下图这样,这是一个典型的 trace 视图,这种展现方式增加显示了执行时间的上下文,相关服务间的层次关系,进程或者任务的串行或并行调用关系。这样的视图有助于发现系统调用的关键路径。通过关注关键路径的执行过程,开发团队就可以专注于优化路径中的关键服务,最大幅度的提升系统性能。例如下图中,我们可以看到请求串行的调用了授权服务、订单服务以及资源服务,在资源服务中又并行的执行了三个子任务。我们还可以看到,在这整个请求的生命周期中,资源服务耗时是最长的。

常见 APM 系统

APM 系统(Application Performance Management,即应用性能管理)是对企业的应用系统进行实时监控,实现对应用性能管理和故障定位的系统化解决方案。APM 作为系统运维管理和网络管理的一个重要方向,能够对关键服务进行监控、追踪以及告警,帮助开发和运维人员轻松地在复杂的应用系统中找到故障点,提高服务的稳定性,保证用户得到良好的服务,降低 IT 运维的成本。 当下成熟的互联网公司都已经建立了全方位监控系统,力求及时发现故障,并为优化系统提供性能数据支持。

国内比较常见的 APM 如下:

  • CAT: 由国内美团点评开源的,基于 Java 语言开发,目前提供 Java、C/C++、Node.js、Python、Go 等语言的客户端,监控数据会全量统计。国内很多公司在用,例如美团点评、携程、拼多多等。CAT 需要开发人员手动在应用程序中埋点,对代码侵入性比较强。

  • Zipkin: 由 Twitter 公司开发并开源,Java 语言实现。侵入性相对于 CAT 要低一点,需要对web.xml 等相关配置文件进行修改,但依然对系统有一定的侵入性。Zipkin 可以轻松与 Spring Cloud 进行集成,也是 Spring Cloud 推荐的 APM 系统。

  • Pinpoint: 韩国团队开源的 APM 产品,运用了字节码增强技术,只需要在启动时添加启动参数即可实现 APM 功能,对代码无侵入。目前支持 Java 和 PHP 语言,底层采用 HBase 来存储数据,探针收集的数据粒度非常细,但性能损耗较大,因其出现的时间较长,完成度也很高,文档也较为丰富,应用的公司较多。

  • SkyWalking: 国人开源的产品,2019 年 4 月 17 日 SkyWalking 从 Apache 基金会的孵化器毕业成为顶级项目。目前 SkyWalking 支持 Java、.Net、Node.js 等探针,数据存储支持MySQL、ElasticSearch等。 SkyWalking 与 Pinpoint 相同,Java 探针采用字节码增强技术实现,对业务代码无侵入。探针采集数据粒度相较于 Pinpoint 来说略粗,但性能表现优秀。目前,SkyWalking 增长势头强劲,社区活跃,中文文档齐全,没有语言障碍,支持多语言探针,这些都是 SkyWalking 的优势所在,还有就是 SkyWalking 支持很多框架,包括很多国产框架,例如,Dubbo、gRPC、SOFARPC 等等,也有很多开发者正在不断向社区提供更多插件以支持更多组件无缝接入 SkyWalking。

  • 还有很多不开源的 APM 系统,例如,淘宝鹰眼、Google Dapper 等等,不再展开介绍了。

SkyWalking 整体架构与核心概念

SkyWalking 是一个基于 OpenTracing 规范的、开源的 APM 系统,它是专门为微服务架构以及云原生架构而设计的。从 SkyWalking 6.0 开始,SkyWalking 将自身定义为一个观测性分析平台(Observability Analysis Platform,OAP)。SkyWalking 的核心功能有:

  • 服务、服务实例、端点指标分析。

  • 服务拓扑图分析

  • 服务、服务实例和端点(Endpoint)SLA 分析

  • 慢查询检测

  • 告警

SkyWalking 如下特点:

  • 多语言自动探针,支持 Java、.NET Code 等多种语言。

  • 为多种开源项目提供了插件,为 Tomcat、 HttpClient、Spring、RabbitMQ、MySQL 等常见基础设施和组件提供了自动探针。

  • 微内核 + 插件的架构,存储、集群管理、使用插件集合都可以进行自由选择。

  • 支持告警。

  • 优秀的可视化效果。

SkyWalking 的架构图如下所示:

SkyWalking 分为三个核心部分:

  • Agent(探针):Agent 运行在各个服务实例中,负责采集服务实例的 Trace 、Metrics 等数据,然后通过 gRPC 方式上报给 SkyWalking 后端。

  • OAP:SkyWalking 的后端服务,其主要责任有两个。

    • 一个是负责接收 Agent 上报上来的 Trace、Metrics 等数据,交给 Analysis Core (涉及 SkyWalking OAP 中的多个模块)进行流式分析,最终将分析得到的结果写入持久化存储中。SkyWalking 可以使用 ElasticSearch、H2、MySQL 等作为其持久化存储,一般线上使用 ElasticSearch 集群作为其后端存储。

    • 另一个是负责响应 SkyWalking UI 界面发送来的查询请求,将前面持久化的数据查询出来,组成正确的响应结果返回给 UI 界面进行展示。

  • UI 界面:SkyWalking 前后端进行分离,该 UI 界面负责将用户的查询操作封装为 GraphQL 请求提交给 OAP 后端触发后续的查询操作,待拿到查询结果之后会在前端负责展示。

这里通过电商系统中的一个接口(请求 path 为"/query/userInfo"),来介绍一下 SkyWalking 中的三个核心概念,如下图所示:

  • Service(服务):用户服务是一个提供独立功能的模块,单独部署成一个集群并对外提供服务,这就是 SkyWalking 中的 Service(服务),这与微服务架构中的一个服务几乎是一样的。

  • ServiceInstance(服务实例):用户服务的集群是由多个部署了同一套代码的 JVM 节点构成的,对外提供了相同的处理能力,当请求进入系统时,由接入层进行负载均衡选择一个节点处理请求。用户服务中一个 JVM 节点即为一个 ServiceInstance(服务实例)。

  • Endpoint(端点):服务对外暴露的接口,例如这里的 "/query/userInfo" 接口,或是其他的 RPC 接口,就是 SkyWalking 中的 Endpoint(端点)。

在后面的课程中,这三个概念会频繁的出现,希望你仔细理解这三个概念之后,再开始后续的学习。

总结

本课时首先通过电商系统的演进,介绍了微服务架构在实际运维和优化工作中遇到的各种问题,然后介绍了 Logging、Metrics、Tracing 等基本概念,并了解了 Trace 系统的由来。随后介绍了APM 系统的概念以及目前市面上常见的 APM 实现。

SkyWalking 作为 APM 系统中的佼佼者,我们介绍了 SkyWalking 的整体架构以及 Service、Endpoint、ServiceInstance 等核心概念。


第02讲:链路追踪利器,快速上手 SkyWalking

在上一课时中,我们介绍了 SkyWalking 的整体架构以及 Service、Endpoint、ServiceInstance 等核心概念。本课时将带领同学们搭建 SkyWalking 的环境搭建,并上手使用 SkyWalking。

SkyWalking 环境搭建

在本课时中,我们将安装并体验 SkyWalking 的基本使用,下面是使用到的相关软件包:

  • apache-skywalking-apm-6.2.0.tar.gz

下载地址:https://archive.apache.org/dist/skywalking/6.2.0/

  • elasticsearch-6.6.1.tar.gz

下载地址:https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.6.1.tar.gz

  • kibana-6.6.1-darwin-x86_64.tar.gz

下载地址:https://artifacts.elastic.co/downloads/kibana/kibana-6.6.1-darwin-x86_64.tar.gz

ElasticSearch 安装

下载完 elasticsearch-6.6.1.tar.gz 包之后,使用如下命令进行解压缩:

tar -zxf elasticsearch-6.6.1.tar.gz

解压完成之后,进入得到的 elasticsearch-6.6.1 目录中,执行如下命令后台启动 ElasticSearch 服务:

./bin/elasticsearch -d

ElasticSearch 启动的相关日志可以通过下面的命令进行查看:

tail -f logs/elasticsearch.log

最后,我们可以请求 localhost:9200 这地址,看到下图输出的这段 JSON 即安装成功:

Kibana 安装

Kibana 是一个开源的分析和可视化平台,主要用于和 Elasticsearch 一起工作,轻松实现 ElasticSearch 的查询和管理。这里使用 ElasticSearch 作为 SkyWalking 的后端存储,在后续调试 SkyWalking 源码时,可能会直接查询 ElasticSearch 中的某些索引,所以这里一并安装 Kibana。

下载完 kibana-6.6.1-darwin-x86_64.tar.gz 安装包之后,我们使用如下命令进行解压:

tar -zxf  kibana-6.6.1-darwin-x86_64.tar.gz

解压完成后进入 kibana-6.6.1-darwin-x86_64 目录,修改 config/kibana.yml 文件:

# 指定上述 ElasticSearch监听的地址,其他配置不变
elasticsearch.hosts: ["http://localhost:9200"]

之后执行如下命令,启动 Kibana 服务:

./bin/kibana

最后我们通过访问 http://localhost:5601/ 地址即可进入 Kibana 界面:

SkyWalking 安装

下载完成 apache-skywalking-apm-6.2.0.tar.gz 包之后,执行如下命令解压缩:

tar -zxf apache-skywalking-apm-6.2.0.tar.gz

解压完成之后进入 apache-skywalking-apm-bin 目录,编辑 config/application.yml 文件,将其中 ElasticSearch 配置项以及其子项的全部注释去掉,将 h2 配置项及其子项全部注释掉,如下图所示,这样 SkyWalking 就从默认的存储 h2 切换成了 ElasticSearch :

接下来执行 ./bin/startup.sh 文件即可启动 SkyWalking OAP 以及 UI 界面,看到的输出如下:

>./bin/startup.sh
SkyWalking OAP started successfully!
SkyWalking Web Application started successfully!

我们可以在 logs/skywalking-oap-server.log 以及 logs/webapp.log 两个日志文件中查看到 SkyWalking OAP 以及 UI 项目的相关日志,这里不再展开。

最后访问 http://127.0.0.1:8080/ 即可看到 SkyWalking 的 Rocketbot UI界面。

Skywalking Agent 目录结构

SkyWalking Agent 使用了 Java  Agent 技术,可以在无需手工埋点的情况下,通过 JVM 接口在运行时将监控代码段插入已有 Java 应用中,实现对 Java 应用的监控。SkyWalking Agent 会将服务运行过程中获得的监控数据通过 gRPC 发送给后端的 OAP 集群进行分析和存储。

SkyWalking 目前提供的 Agent 插件在 apache-skywalking-apm-bin/agent 目录下:

agent├── activations│   ├── apm-toolkit-log4j-1.x-activation-6.2.0.jar│   ├── ...│   └── apm-toolkit-trace-activation-6.2.0.jar├── config # Agent 配置文件│   └── agent.config├── logs # 日志文件├── optional-plugins # 可选插件│   ├── apm-customize-enhance-plugin-6.2.0.jar│   ├── apm-gson-2.x-plugin-6.2.0.jar│   └── ... ...├── plugins # 当前生效插件│   ├── apm-activemq-5.x-plugin-6.2.0.jar│   ├── tomcat-7.x-8.x-plugin-6.2.0.jar│   ├── spring-commons-6.2.0.jar│   └── ... ...└── skywalking-agent.jar

其中,agent.config 文件是 SkyWalking Agent 的唯一配置文件。plugins 目录存储了当前 Agent 生效的插件。optional-plugins 目录存储了一些可选的插件(这些插件可能会影响整个系统的性能或是有版权问题),如果需要使用这些插件,需将相应 jar 包移动到 plugins 目录下。最后的 skywalking-agent.jar 是 Agent 的核心 jar 包,由它负责读取 agent.config 配置文件,加载上述插件 jar 包,运行时收集到 的 Trace 和 Metrics 数据也是由它发送到 OAP 集群的。

skywalking-demo 示例

下面搭建 demo-webapp、demo-provider 两个 Spring-Boot 项目,并且接入 SkyWalking Agent 进行监控,具体结构如下:

demo-webapp 会 Dubbo 远程调用 demo-provider 的接口,而 Dubbo 依赖了 Zookeeper,所以要先安装 Zookeeper。首先下载 zookeeper-3.4.14.tar.gz 包(下载地址:https://archive.apache.org/dist/zookeeper/zookeeper-3.4.14/)。下载完成之后执行如下命令解压缩:

tar -zxf zookeeper-3.4.14.tar.gz

解压完成之后,进入 zookeeper-3.4.14 目录,拷贝 conf/zoo_sample.cfg 文件并重命名为 conf/zoo.cfg,之后执行如下命令启动 Zookeeper:

>./bin/zkServer.sh start
# 下面为输出内容
ZooKeeper JMX enabled by default
Using config: /Users/xxx/zookeeper-3.4.14/bin/../conf/zoo.cfg # 配置文件
Starting zookeeper ... STARTED # 启动成功

下面在 IDEA 中创建 skywalking-demo 项目,并在其中创建 demo-api、demo-webapp、demo-provider 两个 Module,如下图所示:

在 skywalking-demo 下面的 pom.xml 中,将父 pom 指向 spring-boot-starter-parent 并添加 demo-api 作为公共依赖,如下所示:

<project xmlns=..."><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.1.RELEASE</version></parent><groupId>com.xxx</groupId><artifactId>skywalking-demo</artifactId><packaging>pom</packaging><version>1.0-SNAPSHOT</version><modules><module>demo-api</module><module>demo-webapp</module><module>demo-provider</module></modules>

<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.xxx</groupId>
                <artifactId>demo-api</artifactId>
                <version>1.0-SNAPSHOT</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

在 demo-api 中只定义了 HelloService 接口,它是 Dubbo Provider 和 Dubbo Consumer 依赖的公共接口,如下:

public interface HelloService {String say(String name) throws Exception;
}

demo-provider 模块

这里的 demo-provider 扮演了 Dubbo Provider 的角色,在其 pom.xml 文件中引入了 Spring Boot 以及集成 Dubbo 相关的依赖,如下所示:

<dependencies><!-- 引入公共API接口 --><dependency><groupId>com.xxx</groupId><artifactId>demo-api</artifactId><version>1.0-SNAPSHOT</version></dependency><!-- 引入spring-boot-starter以及dubbo和curator的依赖 --><dependency><groupId>com.alibaba.boot</groupId><artifactId>dubbo-spring-boot-starter</artifactId><version>0.2.0</version></dependency><!-- Spring Boot相关依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency>
</dependencies>

demo-provider 模块中的 DefaultHelloService 实现了 HelloService 接口,如下所示:

@Service
@Component
public class DefaultHelloService implements HelloService {

public String say(String name) throws Exception{
        Thread.sleep(2000);
        return “hello” + name;
    }
}

在 resource/application.yml 配置文件中将 DefaultHelloService 实现注册到 Zookeeper上对外暴露为 Dubbo Provider,具体配置如下:

dubbo:application:name: demo-provider # Dubbo Provider 的名字registry:# 注册中心地址,即前面启动的Zookeeper地址address: zookeeper://127.0.0.1:2181 protocol:name: dubbo # 指定通信协议port: 20880 # 通信端口,这里指的是与消费者间的通信协议与端口provider:timeout: 10000 # 配置全局调用服务超时时间,dubbo默认是1s,肯定不够用呀retries: 0 # 不进行重试delay: -1

在 DemoProviderApplication 中提供 Spring Boot 的启动 main() 方法,如下所示:

@EnableDubbo // 添加对 Dubbo支持的注解
@SpringBootApplication
public class DemoProviderApplication {public static void main(String[] args) {SpringApplication.run(DemoProviderApplication.class, args);}
}

为了引入 Skywalking Agent 插件,还需要将 apache-skywalking-apm-bin/agent/config 目录下的 agent.config 配置文件拷贝到 demo-provider 模块的 resource 目录下,并修改其中的 agent.service_name:

# The service name in UI
agent.service_name=${SW_AGENT_NAME:demo-provider}

很明显,agent.config 是一个 KV 结构的配置文件,类似于 properties 文件,value 部分使用 "${}" 包裹,其中使用冒号(":")分为两部分,前半部分是可以覆盖该配置项的系统环境变量名称,后半部分为默认值。例如这里的 agent.service_name 配置项,如果系统环境变量中指定了 SW_AGENT_NAME 值(注意,全是大写),则优先使用环境变量中指定的值,如果环境变量未指定,则使用 demo-provider 这个默认值。

除了系统环境变量的覆盖方式,SkyWalking Agent 还支持另外两种覆盖默认值的方式:

  • JVM 配置覆盖

例如这里的 agent.service_name 配置项,如果在 JVM 启动之前,明确中指定了下面的 JVM 配置:

-Dskywalking.agent.service_name = demo-provider
# "skywalking."是 Skywalking环境变量的默认前缀

则会使用该配置值覆盖 agent.config 配置文件中默认值。

  • 探针配置覆盖

如果将 Java Agent 配置为如下:

-javaagent:/path/skywalking-agent.jar=agent.service_name=demo-provider
# 默认格式是 -javaagent:agent.jar=[option1]=[value1],[option2]=[value2]

则会使用该 Java Agent 配置值覆盖 agent.config 配置文件中 agent.service_name 默认值。

如果四种配置同时出现,则优先级如下:

探针配置 > JVM配置 > 系统环境变量配置 > agent.config文件默认值

编辑好 agent.config 配置文件之后,我们需要在启动 demo-provider 之前通过参数告诉 JVM SkyWalking Agent 配置文件的位置,IDEA 中的配置如下图所示:

最后启动 DemoProviderApplication 这个入口类,可以看到如下输出:

# 查找到 agent.config 配置文件
INFO 2020-02-01 12:12:07:574 main SnifferConfigInitializer :  Config file found in ... agent.config.
# 查找到 agent目录
DEBUG 2020-02-01 12:12:07:650 main AgentPackagePath :  The beacon class location is jar:file:/Users/xxx/...
# Dubbo Provider 注册成功
2020-02-01 12:12:16.105  INFO 58600 --- [main] c.a.d.r.zookeeper.ZookeeperRegistry      :  [DUBBO] Register: dubbo://172.17.32.91:20880/com.xxx.service.HelloService
# demo-provider 启动成功
2020-02-01 12:12:16.269  INFO 58600 --- [           main] com.xxx.DemoProviderApplication          : Started DemoProviderApplication in 4.635 seconds (JVM running for 9.005)

demo-webapp 模块

完成 demo-provider 模块的启动之后,我们继续来开发 demo-webapp 模块,其 pom.xml 与 demo-provider 中的 pom.xml 相比,多引入了 spring-boot 对 Web开发的依赖,以及 SkyWalking 提供的 apm-toolkit-trace 依赖用来获取 TraceId:

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

<!-- apm-toolkit-trace 这个依赖主要用来获取 TraceId -->
<dependency>
    <groupId>org.apache.skywalking</groupId>
    <artifactId>apm-toolkit-trace</artifactId>
    <version>6.2.0</version>
</dependency>

首先,在 HelloWorldController 中提供了两个接口:

  • /hello/{words} 接口:通过 Dubbo 远程调用 demo-provider 暴露的接口。
  • /err 接口:直接抛出 RuntimeException 异常。

HelloWorldController 的具体实现如下:

@RestController
@RequestMapping("/")
public class HelloWorldController {@Referenceprivate HelloService helloService;

@GetMapping(“/hello/{words}”)
    public String hello(@PathVariable(“words”) String words) 
            throws Exception{
        Thread.sleep(1000);
        // TraceContext 工具类定义在 apm-toolkit-trace 依赖包中
        log.info(“traceId:{}”, TraceContext.traceId());
        ActiveSpan.tag(“hello-trace”, words);
        String say = helloService.say(words);
        Thread.sleep(1000);
        return say;
    }

@GetMapping(“/err”)
    public String err() {
        String traceId =  TraceContext.traceId();
        log.info(“traceId:{}”, traceId);
        ActiveSpan.tag(“error-trace activation”, “error”);
        throw new RuntimeException(“err”);
    }

在 resources/application.yml 文件中会配置 demo-webapp 监听的端口、Zookeeper 地址以及 Dubbo Consumer 的名称等等,具体配置如下:

server:port: 8000

dubbo:
  application:
    name: demo-webapp # Dubbo Consumer名字
  registry:
    address: zookeeper://127.0.0.1:2181 # 注册中心地址,即 Zookeeper地址

demo-webpp 模块也需要在 resource 目录下添加 agent.config 配置文件,并修改其 agent.service_name 配置项,如下所示:

# The service name in UI
agent.service_name=${SW_AGENT_NAME:demo-webapp}

demo-webpp 模块的入口 main() 方法与 demo-provider 相同,不再赘述。

为了接入 SkyWalking Agent,启动 demo-webapp 项目之前也需要配置相应的 VM options 参数,指定 agent.config 配置文件的地址,如下图所示:

最后,启动 demo-webapp 项目,通过浏览器访问 http://localhost:8000/hello/xxx 地址得到正常相应,访问 http://localhost:8000/err 得到 500 响应,即表示启动成功。

到此为止,SkyWalking Agent 的基本接入方式就介绍完了,在后面分析和改造 SkyWalking 源码时,还可以使用 demo-webapp 和 demo-provider 这两个应用来产生 Trace 和 Metrics 数据。

SkyWalking Rocketbot 使用

搭建完 SkyWalking 环境以及相关示例之后,我们来看如何使用 SkyWalking 提供的 UI 界面—— Skywalking Rocketbot。在前面执行的 ./bin/startup.sh 脚本,除了启动后端 OAP 服务,同时还会启动 Skywalking Rocketbot(位于 webapp 目录下的 skywalking-webapp.jar)。

如下图所示,在 Skywalking Rocketbot 首页顶部(1)处,有四个主 Tab 页,在【仪表盘】这个 Tab 中,(2)处可以选择查询的服务(Service)、端点(Endpoint) 以及服务实例(ServiceInstance)。在(3)处可以选择展示的不同维度,下图展示了 Global 这个全局视图:

其中有五个面板((4)~(8)),分别是:

  • Global Heatmap 面板:热力图,从全局展示了某段时间请求的热度。
  • Global Percent Response 面板 :展示了全局请求响应时间的 P99、P95、P75 等分位数。
  • Global Brief 面板:展示了 SkyWalking 能感知到的 Service、Endpoint 的个数。
  • Global Top Troughput 面板:展示了吞吐量前几名的服务。
  • Global Top Slow Endpoint 面板:展示了耗时前几名的 Endpoint。

除了 SkyWalking Rocketbot 默认提供的这些面板,我们还可以点击(2)处左边的锁型按钮,自定义 Global 面板。另外,我们还可以通过(9)处的时间选择框选择自定义查询的时间段。

将(3)处切换到 Service 面板,可以看到针对 Service 的监控面板,如下图所示:

  • Service (Avg) ResponseTime 面板:展示了指定服务的(平均)耗时。
  • Service (Avg) Throughput 面板:展示了指定服务的(平均)吞吐量。
  • Service (Avg) SLA 面板:展示了指定服务的(平均)SLA(Service Level Agreement,服务等级协议)。
  • Service Percent Response 面板:展示了指定服务响应时间的分位数。
  • Service Slow Endpoint 面板:展示了指定服务中耗时比较长的 Endpoint 信息。
  • Running ServiceInstance 面板:展示了指定服务下的实例信息。

将(3)处切换到 Endpoint 面板,可以看到针对 Endpoint 的监控面板,基本功能与 Service 面板类似,这里不再展开。

将(3)处切换到 Instance 面板,可以看到针对 ServiceInstance 的监控面板,如下图所示:

     
在 ServiceInstance 面板中展示了很多 ServiceInstance 相关的监控信息,例如,JVM 内存使用情况、GC 次数、GC 耗时、CPU 使用率、ServiceInstance SLA 等等信息,这里不再一一展开介绍。

下面我们切换到【拓扑图】这个主 Tab,如下图所示,在(1)处展示当前整个业务服务的拓扑图。点击拓扑图中的任意节点,可在(2)处看到服务相应的状态信息,其中包括响应的平均耗时、SLA 等监控信息。点击拓扑图中任意一条边,可在(3)处看到一条调用链路的监控信息,其中会分别从客户端(上游调用方)和服务端(下游接收方)来观测这条调用链路的状态,其中展示了该条链路的耗时、吞吐量、SLA 等信息:

下面我们切换到【追踪】这个主 Tab来查询 Trace 信息,如下图所示。在(1)、(2)处可以选择 Trace 的查询条件,其中可以指定 Trace 涉及到的 Service、ServiceInstance、Endpoint 以及Trace 的状态继续模糊查询,还可以指定 TraceId 和时间范围进行精确查询。在(3)处展示了 Trace 的简略信息,下图中 "/err" 接口这条 Trace 被显示为红色表示该 Trace 关联的请求出现了异常。在(4)和(5)处展示了 Trace 的具体信息以及所有 Span 信息,我们可以通过(6)处按钮调整 Span 的展示方式:

点击 Trace 中的 Span,就可以将该 Span 的具体信息展示出来,如下下图所示,点击"/err" 接口相关 Trace 中的 Span,即可看到相应的 TRuntimeException 异常信息:

最后,我们将主 Tab 也切换到【告警】,这里展示了 Skywalking 发出来的告警信息,如下图所示,这里也提供了相应的查询条件和关键字搜索框。

总结

本课时搭建 SkyWalking 的运行环境,完成 ElasticSearch、Kibana、Skywalking 等的安装,并搭建了 skywalking-demo 项目作为演示示例,带同学们上手体验了 Skywalking Agent 的接入的流程。

最后介绍了 SkyWalking Rocketbot UI 界面强大的功能,包括 Service、Endpoint、ServiceInstance 等不同级别的监控,展示了整个服务的拓扑图、Trace 查询以及告警信息查询等功能。


微服务链路追踪SkyWalking第一课 SkyWalking简介相关推荐

  1. SkyWalking 微服务链路追踪

    目录 8. SkyWalking 微服务链路追踪 8.1 介绍 SkyWalking 8.2 Skywalking---服务搭建 8.3 SkyWalking---接入服务 8.3.1 windows ...

  2. 微服务链路追踪-SkyWalking

    微服务链路追踪-SkyWalking SkyWalking官网地址:https://skywalking.apache.org/ SkyWalking官方文档:https://skywalking.a ...

  3. 微服务链路追踪SkyWalking

    微服务链路追踪SkyWalking 链路追踪介绍 skywalking是什么 SkyWalking环境搭建部署 SkyWalking跨多个微服务跟踪 SkyWalking UI介绍 SkyWalkin ...

  4. 微服务链路追踪SkyWalking第十一课 OAL详解实战

    第31讲:OAL 语言,原来定义创造一门新语言如此轻松(上) 在前文介绍 Metrics 实现以及对应的 DIspatcher 实现的时候,会发现有一部分实现类位于 generated-analysi ...

  5. 微服务链路追踪SkyWalking第八课 OAP的receiver模块详解

    第22讲:深入剖析 regiter-receiver-plugin 插件(上) 在上一课时中,重点介绍了 SkyWalking 存储层的框架设计以及核心接口.从本节课开始,我们将深入 SkyWalki ...

  6. skywalking原理_微服务链路追踪原理

    作者:平也 来源:关爱程序员社区 背景介绍 在微服务横行的时代,服务化思维逐渐成为了程序员的基本思维模式,但是,由于绝大部分项目只是一味地增加服务,并没有对其妥善管理,当接口出现问题时,很难从错综复杂 ...

  7. 全网最全的微服务链路追踪实践-SkyWalking(看这一篇就够了)

    链路追踪介绍 对于一个大型的几十个.几百个微服务构成的微服务架构系统,通常会遇到下面一些问题,比如: 1. 如何串联整个调用链路,快速定位问题? 2. 如何缕清各个微服务之间的依赖关系? 3. 如何进 ...

  8. 阿里P7架构师详解微服务链路追踪原理

    背景介绍 在微服务横行的时代,服务化思维逐渐成为了程序员的基本思维模式,但是,由于绝大部分项目只是一味地增加服务,并没有对其妥善管理,当接口出现问题时,很难从错综复杂的服务调用网络中找到问题根源,从而 ...

  9. 微服务链路追踪_.NET Core微服务:分布式链路追踪系统分享

    (给DotNet加星标,提升.Net技能) 转自:另一个老李 cnblogs.com/SteveLee/p/10463200.html 对于普通系统或者服务来说,一般通过打日志来进行埋点,然后再通过e ...

最新文章

  1. Linux 创建、删除、修改 文件夹 文件命令(笔记)
  2. MySQL存储过程简介
  3. ubuntu安装时发现GPT分区表,无法安装问题
  4. Telnet 1433端口
  5. iPhone 13供需接近平衡,iPhone 13 Pro交付时间较长
  6. Python向下取整整除运算符用法一例
  7. 酒店居然用大数据赚你钱?
  8. oracle 12c容器数据库备份和恢复,oracle 12c数据库备份与恢复
  9. Sublime Merge for Mac(git客户端软件)
  10. 常用的字符串对象方法
  11. ryujinx模拟器linux安装教学,switch模拟器Ryujinx
  12. 高效能人士的七个习惯--由内而外全面造就自己
  13. matlab 生命游戏(可调节代数,存活条件,繁殖条件)
  14. Redis学习笔记~Redis事务机制与Lind.DDD.Repositories.Redis事务机制的实现
  15. MAC安装JDK及环境变量配置
  16. flash遍历子元件_Flash编程-详解循环语句
  17. MPI之点对点通信——阻塞式MPI_Send 和MPI_Recv
  18. php json数据中 双引号变为quot;解决
  19. macino404 || cinema 4D 基础解释 || 第一篇
  20. Dalvik和ART

热门文章

  1. 小猿圈之初识python基础知识
  2. 用python实现等额本息
  3. 基于微信小程序的音乐播放器设计
  4. ASP.Net Core实战——身份认证(JWT鉴权)
  5. 循环结构验证哥德巴赫猜想
  6. 163VIP邮箱哪个用的多?邮件误删恢复怎么操作?
  7. Retrofit 大体框架
  8. 枚举型、注释(待补充)
  9. windows mobile数据同步方案
  10. Python制作牛奶冻