踏雪留痕:分布式链路追踪框架——Skywalking

序言

  对于个大型的几十个、 几百个微服务构成的微服务架构系统, 通常会遇到下面一些问题,比如:

  • 如何捋清各个微服务间的依赖关系?
  • 如何跟踪整个业务流程的调用处理顺序?
  • 如何进行各个微服务接口的性能分折?
  • 如何串联整个调用链路日志,快速定位问题?

  要处理这些问题,就需要分布式链路追踪框架出手了,本文要谈的 Skywalking 就是一款分布式链路追踪框架。

简介

  Skywalking 是一款分布式系统的应用程序性能监视工具, 专为微服务、云原生架构和基于容器(Docker、K8s、Mesos) 架构而设计。它是一款优秀的 APM (Application Performance Management) 工具,包括了分布式追踪、性能指标分析、应用和服务依赖分析等。

为什么选择 Skywalking?

  目前,市面上的链路追踪框架大概有以下几种:

  • Zipkin:Twitter 开源的调用链分析工具,目前基于 SpringCloud sleuth 得到了广泛的使用,特点是轻量,使用部署简单
  • Pinpoint:韩国人开源的基于字节码注入的调用链分析,以及应用监控分析工具。特点是支持多种插件,UI 功能强大,接入端无代码侵入
  • SkyWalking:国产开源的基于字节码注入的调用链分析,以及应用监控分析工具。特点是支持多种插件,UI 功能较强,接入端无代码侵入
  • CAT:大众点评开源的基于编码和配置的调用链分析,应用监控分析,日志采集,监控报警等一系列的监控平台工具

功能对比

支持功能\种类 Cat Zipkin Skywalking
调用链可视化
聚合报表 非常丰富 较丰富
服务依赖图 简单 简单
埋点方式 侵入式 侵入式 非侵入字节码增强
VM监控指标
支持语言 Java/.Net 丰富 Java/.Net/Nodejs/php/Go
存储机制 MySQL(报表)、本地文件/HDFS 内存、ES. MySQL 等 H2、ES
社区支持 主要在国内 国外主流 Apache 支持
使用案例 美团、携程 京东、阿里定制后不开源 华为、小米、当当、 微众银行
APM
开发基础 eBay cal Google Dapper Google Dapper
是否支持 web flux

性能对比

  通过 Jmeter 测试,各指标配置:

  • 采样率为 1,即 100%
  • 分别模拟并发用户数:500,750,1000
  • 每个线程发送 30 个请求,设置思考时间为 10ms
  • pinpoint默认的采样率为20,即 50%
  • 通过设置agent的配置文件改为 100%。 zipkin 默认也是1

  组合起来,一共有 12 种,测试得到结果汇总表:

APM 采样率 线程数 请求总数 平均请求时间 ms 最小请求时间ms 最大请求时间ms 90%Line 错误率% CPU memory Throughput /sec
none 1 500 15000 17 9 824 21 0 45% 50% 1385
Zipkin 1 500 15000 117 10 2101 263 0 56% 55% 990
Skywallking 1 500 15000 22 10 1026 23 0 50% 52% 1228
Pinpoint 1 500 15000 201 10 7236 746 0 48% 52% 774
none 1 750 22500 321 10 15107 991 0 56% 48% 956
Zipkin 1 750 22500 489 10 27614 1169 0 63% 55% 582
Skywalking 1 750 22500 396 10 16478 941 0 55% 50% 908
Pinpoint 1 750 22500 681 10 28138 1919 0 56% 48% 559
none 1 1000 30000 704 10 39772 1621 0 59% 53% 557
Zipkin 1 1000 30000 1021 10 36836 1978 0 63% 55% 533
Skywalking 1 1000 30000 824 10 25983 1758 0 62% 55% 667
Pinpoint 1 1000 30000 1148 10 40971 2648 0 60% 52% 514

  从上表可以看出,在三种链路监控组件中,Skywalking 的探针对吞吐量的影响最小, Zipkin 的吞吐量居中,Pinpoint 的探针对吞吐量的影响较为明显, 在 500 并发用户时,测试服务 的吞吐量从 1385 降低到 774,影响很大。
  另外,观测 CPU 和 memory 的影响, 可看到压测时对 CPU 和 memory 的影响都差不多在 10% 之内。

功能特性

  • 支持告警
  • 优秀的可视化解决方案
  • 轻量高效,无需大数据平台和大量的服务器资源
  • 模块化,UI、 存储、集群管理都有多种机制可选
  • 支持多种语言自动探针,包括 Java, .NET Core 和 Node.JS
  • 多种监控手段,可以通过语言探针和 Service Mesh 获得监控的数据

工作原理

核心组成

  从上图克制,Skywalking 核心由四个组件构成:

  • skywalking-agent:和业务应用(SpringBoot)绑定在一起,负责收集各种监控数据
  • skywalking-oapservice:通常以集群的形式存在,主要负责:
    • 处理监控数据:接收skywalking agent绑定应用的监控数据,并存储在数据库中;
    • 处理查询请求:接收skywalking webapp前端请求,从数据库查询数据返回给前端
  • skywalking-webapp:前端界面,用于展示数据
  • 存储端:使用相关数据库(MySQL、ES 等)存储监控数据

环境搭建

下载

  从 Skywalking 下载地址 获取即可。

  注意:Skywalking 在 8.8.0 后skywalking-agent.jarskywalking-apm包中额外拆分出来了,需要点此下载

目录结构

  apache-skywalking-apm-8.9.0.tar.gz压缩包解压后目录结构如下:

  • bin目录:存放各种启动脚本,一般使用脚本startup.sh来启动 web 页面和对应的后台应用;
    • oapService.*:默认使用的后台程序的启动脚本; (使用的是默认模式启动,还支持其他模式,各模式区别见启动模式)
    • oapServicelnit.*init模式启动;在此模式下,OAP 服务器启动以执行初始化工作,然后退出
    • oapServiceNolnit.*:使用no init模式启动;在此模式下,OAP 服务器不进行初始化
    • webappService.*: UI前端的启动脚本
    • startup.*: 组合脚本,同时启动oapService.*. webappService.*脚本
  • config: 启动后台应用程序的配置文件, 是使用的各种配置
  • oap-libs:后台应用的 jar 包,以及它的依赖 jar 包,里边有一个server-starter-*jar就是启动程序;
  • webapp: 存放 UI 前端的 jar 包和配置文件

  apache-skywalking-java-agent-8.14.0.tgz压缩包解压后目录结构如下:

  • skywalking-agent.jar:代理服务 jar 包
  • config:代理服务启动时使用的配置文件
  • plugins: 包含多个插件,代理服务启动时会加载改目录下的所有插件(实际是各种 jar 包)
  • optional-plugins:可选插件,当需要支持某种功能时,比如 SpringCloud Gateway,则需要把对应的 jar 包拷贝到此目录

启动

  在apmbin目录下,执行startup.sh脚本成功后,会启动两个服务:

  • skywalking-oap-server:启动后会暴露 11800 端口(收集监控数据)和 12800 端口(接受前端请求),若要修改上述端口,可在config/applicaiton.yml文件进行配置,此服务可单独执行oapService.sh脚本启动
  • skywalking-web-uiSkywalking 的 UI 控制台,启动后会暴露 8080 端口,若端口其他应用冲突,可以在webapp/webapp.yml文件配置新的端口,此服务可单独执行webappService.sh脚本启动

停止

1
2
3
4
5
jps
85555 OAPServerStartUp
85560 skywalking-webapp.jar

kill -9 85555 85560

功能集成

  Skywalking 的 UI 界面导航栏包含系列菜单支撑其功能:

  • 仪表盘
  • 拓扑图
  • 追踪
  • 性能剖析
  • 日志
  • 告警

  当然,要想使用这些功能,前提是在对应服务集成 Skywalking。

前提:微服务端集成

  Skywalking 可以跨越多个微服务跟踪相关指标,只需要每个微服务启动时添加javaagent参数即可,因此配置 Skywalking 的 JVM 参数后,再分别启动相关微服务即可:

1
-javaagent:/Users/wk/software/skywalking/skywalking-agent/skywalking-agent.jar -DSW_AGENT_NAME=user-service

仪表盘

  仪表盘中可以查看一些指标数据:

仪表盘

拓扑图

  拓扑图中可以查看一些服务的状态:

拓扑图

追踪

  追踪可以查看一个请求接口调用的整个服务的状况:

追踪

业务追踪

  如果我们希望对项目中的业务方法, 实现链路追踪,方便我们排查问题, 可以使用如下的代码引入依赖:

1
2
3
4
5
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-trace</artifactId>
<version>8.9.0</version>
</dependency>

业务方法加入追踪链路

  如果一个业务方法想在 UI 界面的跟踪链路上显示出来, 只需要在业务方法上加上@Trace注解即可。

记录业务方法信息

  Skywalking 可以为追踪链路增加其他额外的信息,比如记录参数和返回信息。

  实现方式:在方法上增加@Tag或者@Tags,具体见下面代码:

1
2
3
4
5
6
7
8
9
10
11
12
@Trace
@Tag(key = "list", value = "returned0bj" )
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);
}

性能剖析

  性能剖析可以针对指定接口方法进行监控,寻找出执行缓慢的代码。

  若想使用此功能,在性能剖析菜单新建任务,之后配置即可。

性能剖析中新增任务

  性能剖析使用时需要注意亮点:

  • 一个服务在监控持续时间内只能设置一个端点监控任务
  • 监控的端点前缀需要增加 HTTP 请求类型:如/dict/type/simpleList是无法监控的,需要使用GET:/dict/type/simpleList才行,因此上面的图配置是不对的
  • 剖析端点的响应时间必须大于监控间隔时间,如果响应时间小于监控间隔时间,则无法进行采集监控。若想进行测试,可以将相关接口使用线程睡眠 500ms,这么做之后在性能剖析中新建对应任务后就能观察到

日志

  如何跟踪一个请求调用后端应用后的整个方法流程?

  在单体项目中,我们会使用 MDC 在日志增加一个请求的全局唯一 ID 以跟踪整个调用方法栈,但是 MDC 内部使用的是 ThreadLocal 进行实现,所以只有本线程才有效,子线程和下游的服务 MDC 里的值会丢失。

  对于微服务项目,由于一个请求可能涉及到多个服务的调用,ThreadLocal 实现的 MDC 将不太适用了。

  SkyWalking 是基于服务的追踪框架,服务追踪的实现思路是通过某些手段给目标应用注入追踪探针(Probe),因此 SkyWalking 非常适用微服务项目。

引入依赖

1
2
3
4
5
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-logback-1.x</artifactId>
<version>8.9.0</version>
</dependency>

配置日志文件

  logback.xml文件按如下配置即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<property name="SKYWALKING_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{tid}] %-5p ${PID:- } --- [%t] %logger{36} : %m%n"/>

<!-- 控制台输出 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<charset>UTF-8</charset>
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.mdc.TraceIdMDCPatternLogbackLayout">
<Pattern>${SKYWALKING_LOG_PATTERN}</Pattern>
</layout>
</encoder>
</appender>

<!-- Skywalking -->
<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.mdc.TraceIdMDCPatternLogbackLayout">
<Pattern>${SKYWALKING_LOG_PATTERN}</Pattern>
</layout>
</encoder>
</appender>

<!-- 开发环境 -->
<springProfile name="dev">
<!-- 应用日志 -->
<root level="INFO">
<appender-ref ref="console"/>
<appender-ref ref="asyncAppLog"/>
<appender-ref ref="grpc-log"/>
<appender-ref ref="errorLog"/>
</root>
</springProfile>

  以上配置主要是进行了如下操作:

  • 控制台日志变更为 skywalking 格式配置输出
  • 记录 grpc-log 并异步输出到 skywalking 的存储端

  详细配置见 Skywalking 与 Logback 集成说明

  注意不要使用异步日志,否则 UI 界面会没有追踪 ID。

配置 Agent

1
vim agent.config

  末尾增加以下配置:

1
2
3
4
5
6
7
8
9
10
# 接收skywalking trace数据的后端地址
collector.backend_service=${SW_AGENT_COLLECTOR_BACKEND_SERVICES:192.168.1.22:11800}
# 指定要向其报告日志数据的grpc服务器的主机,SW_GRPC_LOG_SERVER_HOST 需要修改
plugin.toolkit.log.grpc.reporter.server_host=${SW_GRPC_LOG_SERVER_HOST:192.168.1.22}
# 指定要向其报告日志数据的grpc服务器的端口
plugin.toolkit.log.grpc.reporter.server_port=${SW_GRPC_LOG_SERVER_PORT:11800}
# 指定grpc客户端要报告的日志数据的最大大小
plugin.toolkit.log.grpc.reporter.max_message_size=${SW_GRPC_LOG_MAX_MESSAGE_SIZE:10485760}
# 客户端向上游发送数据时将超时多长时间。单位是秒
plugin.toolkit.log.grpc.reporter.upstream_timeout=${SW_GRPC_LOG_GRPC_UPSTREAM_TIMEOUT:30}

  注意:plugin.toolkit.log.grpc.reporter.server_hostcollector.backend_service 是两个不同的配置项,具有不同的作用:

  • plugin.toolkit.log.grpc.reporter.server_host: 用于配置 SkyWalking Agent 中日志收集器(LogCollector)将数据上报到的 SkyWalking OAP 服务地址。这个配置项只影响日志收集器的行为,不会影响 Tracing 数据的上报。
  • collector.backend_service: 用于配置 SkyWalking Agent 上报 Trace 和 Metric 数据的 SkyWalking OAP 服务地址。这个配置项影响整个 SkyWalking Agent 的行为,包括 Tracing 和 Metrics 数据的上报。

  简单来说,plugin.toolkit.log.grpc.reporter.server_host 只是影响日志收集器上报数据的地址,而 collector.backend_service 影响整个 SkyWalking Agent 上报数据的地址,包括 Tracing 和 Metrics 数据。

  所以,上述配置可以优化为:

1
2
3
4
5
6
# 接收 skywalking 数据的后端地址,可以配置多个,按 , 隔开
collector.backend_service=${SW_AGENT_COLLECTOR_BACKEND_SERVICES:192.168.1.22:11800,192.168.1.23:11800}
# 指定grpc客户端要报告的日志数据的最大大小
plugin.toolkit.log.grpc.reporter.max_message_size=${SW_GRPC_LOG_MAX_MESSAGE_SIZE:10485760}
# 客户端向上游发送数据时将超时多长时间。单位是秒
plugin.toolkit.log.grpc.reporter.upstream_timeout=${SW_GRPC_LOG_GRPC_UPSTREAM_TIMEOUT:30}

告警

  SkyWalking 告警功能在 6.x 版本引入, 其核心由一组规则驱动,规则触发后通知相关服务。

  告警功能定义分为两部分:

  • 告警规则:定义什么条件下触发度量警报
  • Webhook(网络钩子): 定义当警告触发时, 哪些服务终端需要被告知

告警规则

  告警规则定义了什么条件下触发度量警报。

默认的告警规则

  SkyWalking 的发行版预先定义了一些默认的告警规则:

  • 过去 3 分钟内服务平均响应时间超过 1 秒
  • 过去 2 分钟服务成功率低于 80%
  • 过去 3 分钟内服务响应时间超过 1s 的百分比
  • 服务实例在过去 2 分钟内平均响应时间超过 1s, 并且实例名称与正则表达式匹配
  • 过去 2 分钟内端点平均响应时间超过 1 秒
  • 过去 2 分钟内数据库访问平均响应时间超过 1 秒
  • 过去 2 分钟内端点关系平均响应时间超过 1 秒

  这些预定义的告警规则, 在config/alarm-settings.yml文件中可以看到。

告警规则配置说明

  告警规则配置项的说明:

  • Rule name: 规则名称,也是在告警信息中显示的唯一名称。 必须以_rule结尾,前缀可自定义
  • Metrics name: 度量名称, 取值为oal脚本中的度量名,目前只支持 long、 double 和 int 类型
  • Include names: 该规则作用于哪些实体名称,比如服务名, 终端名(可选,默认为全部)
  • Exclude names: 该规则作不用于哪些实体名称,比如服务名, 终端名(可选,默认为空)
  • Threshold: 阈值
  • OP:操作符,目前支持 >、<、=
  • Period:多久告警规则需要被核实一下。 这是一个时间窗口, 与后端部署环境时间相匹配
  • Count:在一个Period窗口中, 如果values超过Threshold值 (按op), 达到Count值, 雲要发送警报
  • Silence period:在时间N中触发振警后,在TN-> TN + period这个阶段不告警。默认情况下, 它和Period- 样,这意味看相同的告警(在同一个Metrics name拥有相同的ld)在同一个Period内只会触发一次
  • message:告警消息

Webhook (网络钩子)

  Webhook(网络钩子),定义了当警告触发时, 哪些服务终端需要被告知。

  Webhook 可以简单理解为是一种 Web 层面的回调机制, 通常由一些事件触发,与代码中的事件回调类似,只不过是 Web 层面的。由于是 Web 层面的,所以当事件发生时,回调的不再是代码中的方法或函数,而是服务接口。例如,在告警这个场景,告警就是一个事件。当该事件发生时, SkyWalking 就会主动去调用一 个配好的接口,该接口就是所谓的 Webhook。

  SkyWalking 的告警消息会通过 HTTP 请求进行发送,请求方法为 POST,Content-Type 为application/json

最佳实践

版本建议

  Skywalking APM 建议使用 8.9.1 版本,9.X 版本存在大改,但大多功能用不到,若一定要用 9.X 版本,建议使用 9.3.0,因为后续版本不支持 JDK 8.

  Skywalking Agent 建议使用 8.14.0 版本,因为低版本存在一些 Bug.

持久化

  默认情况下,Skywalking 数据是存放到内存当中,若要持久化到其他数据库中需要修改config/application.yml文件,之后重启即可。

基于 ES 持久化(常用)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
storage:
# 存储端设置为 ES
selector: ${SW_STORAGE:elasticsearch}
# 按具体设置修改
elasticsearch:
# skywalking 的索引前缀,默认为sw
namespace: ${SW_NAMESPACE:""}
# 存储的 ES 节点地址
clusterNodes: ${SW_STORAGE_ES_CLUSTER_NODES:192.168.1.22:9200}
protocol: ${SW_STORAGE_ES_HTTP_PROTOCOL:"http"}
connectTimeout: ${SW_STORAGE_ES_CONNECT_TIMEOUT:500}
socketTimeout: ${SW_STORAGE_ES_SOCKET_TIMEOUT:30000}
numHttpClientThread: ${SW_STORAGE_ES_NUM_HTTP_CLIENT_THREAD:0}
user: ${SW_ES_USER:""}
password: ${SW_ES_PASSWORD:""}
trustStorePath: ${SW_STORAGE_ES_SSL_JKS_PATH:""}
trustStorePass: ${SW_STORAGE_ES_SSL_JKS_PASS:""}
# 属性格式的秘密管理文件包括用户名、密码,由第三方工具管理
secretsManagementFile: ${SW_ES_SECRETS_MANAGEMENT_FILE:""}
# 代表一分钟/小时/天的指数中的天数
dayStep: ${SW_STORAGE_DAY_STEP:1}
# 新索引的主分片数
indexShardsNumber: ${SW_STORAGE_ES_INDEX_SHARDS_NUMBER:1}
# 新索引的副本分片数,默认为1,这里设置为0
indexReplicasNumber: ${SW_STORAGE_ES_INDEX_REPLICAS_NUMBER:0}
# 在代码中已经定义了超级数据集,如跟踪段。以下三个配置将提高 ES 在存储超级大小数据时的性能
### 代表超大规模数据集记录索引中的天数,当数值小于0时,默认值与dayStep相同
superDatasetDayStep: ${SW_SUPERDATASET_STORAGE_DAY_STEP:-1}
### 这个因素为超级数据集提供了更多的碎片,碎片数=indexShardsNumber * superDatasetIndexShardsFactor。另外,这个因素还影响Zipkin和Jaeger的追踪
superDatasetIndexShardsFactor: ${SW_STORAGE_ES_SUPER_DATASET_INDEX_SHARDS_FACTOR:5}
### 代表超大型数据集记录索引中的复制数量,默认值为0。
superDatasetIndexReplicasNumber: ${SW_STORAGE_ES_SUPER_DATASET_INDEX_REPLICAS_NUMBER:0}
# 索引模板的顺序
indexTemplateOrder: ${SW_STORAGE_ES_INDEX_TEMPLATE_ORDER:0}
# 每当 ${SW_STORAGE_ES_BULK_ACTIONS} 请求时,执行异步批量记录数据
bulkActions: ${SW_STORAGE_ES_BULK_ACTIONS:5000}
# 每10秒刷新一次,无论请求的数量是多少,INT(flushInterval * 2/3)都将被用于索引刷新期
flushInterval: ${SW_STORAGE_ES_FLUSH_INTERVAL:15}
# 并发请求的数量
concurrentRequests: ${SW_STORAGE_ES_CONCURRENT_REQUESTS:2}
resultWindowMaxSize: ${SW_STORAGE_ES_QUERY_MAX_WINDOW_SIZE:10000}
metadataQueryMaxSize: ${SW_STORAGE_ES_QUERY_MAX_SIZE:5000}
segmentQueryMaxSize: ${SW_STORAGE_ES_QUERY_SEGMENT_SIZE:200}
profileTaskQueryMaxSize: ${SW_STORAGE_ES_QUERY_PROFILE_TASK_SIZE:200}
# OAP分析器
oapAnalyzer: ${SW_STORAGE_ES_OAP_ANALYZER:"{\"analyzer\":{\"oap_analyzer\":{\"type\":\"stop\"}}}"}
# oap日志分析器。它可以通过ES分析器的配置进行定制,以支持更多的语言日志格式,如中文日志、日文日志等
oapLogAnalyzer: ${SW_STORAGE_ES_OAP_LOG_ANALYZER:"{\"analyzer\":{\"oap_log_analyzer\":{\"type\":\"standard\"}}}"}
advanced: ${SW_STORAGE_ES_ADVANCED:""}

踩坑记录

1
Elasticsearch exception [type=index_not_found_exception, reason=no such index]

  重启 oap 服务或者删除 ES Skywalking 对应索引数据。

基于 MySQL 持久化(不推荐)

1
2
3
4
5
6
7
8
9
storage:
#selector: ${SW_STORAGE:h2}
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@1234}

踩坑记录

  由于oap-libs目录下没有 MySQL 相关驱动包,所以 Skywalking 无法重启成功,解决方法是将 MySQL 的驱动包复制一份过来。

高可用

  在大多数生产环境中,后端应用需要支持高吞吐量并且支持高可用来保证服务的稳定,所以在生产环境需要搭建应用集群。

  Skywalking 集群是将多个 OAP 作为服务注册到 Nacos 上,只要 OAP 服务没有全部宕机,保证有一个在运行,就能进行链路跟踪。

  搭建一个 skywalking oap 集群需要:

  • 至少一个 Nacos(亦可用集群)
  • 至少一个 ES(建议)/MySQL(亦可用集群)
  • 至少两个 OAP 服务
  • 至少一个 WEB-UI 服务
  • 修改config/application.yml文件使用nacos作为注册中心
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    cluster:
    #selector: ${SW_CLUSTER:standalone}
    # 修改为 Nacos,更改具体配置信息即可
    selector: ${SW_CLUSTER:nacos}
    nacos:
    serviceName: ${SW_SERVICE_NAME:"SkyWalking_OAP_Cluster"}
    hostPort: ${SW_CLUSTER_NACOS_HOST_PORT:localhost:8848}
    # Nacos Configuration namespace
    namespace: ${SW_CLUSTER_NACOS_NAMESPACE:"public"}
    # Nacos auth username
    username: ${SW_CLUSTER_NACOS_USERNAME:""}
    password: ${SW_CLUSTER_NACOS_PASSWORD:""}
    # Nacos auth accessKey
    accessKey: ${SW_CLUSTER_NACOS_ACCESSKEY:""}
    secretKey: ${SW_CLUSTER_NACOS_SECRETKEY:""}

过期策略

  在 SkyWalking 中,有两种类型的可观察性数据:

  • recordData:包括 traces, logs, topN sampled statements、alarm,即追踪、日志、topN 采样语句和告警数据
  • metricsData:包括 metrics for service, instance, endpoint, topology map(即服务、实例、端点和拓扑图的所有度量)。Metadata(lists of services, instances,endpoints,即元数据(服务、实例或端点的列表)也属于度量

  这些数据在 Skywalking 的存储端不会永久保存,存在过期时间,其配置对应application.yml文件的以下配置:

1
2
3
4
5
6
7
8
9
10
core:
......
# 是否开启数据过期清理定时任务,默认开启
enableDataKeeperExecutor: ${SW_CORE_ENABLE_DATA_KEEPER_EXECUTOR:true}
# 数据过期清理定时任务执行频率,默认 5 分钟执行一次
dataKeeperExecutePeriod: ${SW_CORE_DATA_KEEPER_EXECUTE_PERIOD:5}
# recordDataTTL 作用于 recordData,默认过期时间是 3 天
recordDataTTL: ${SW_CORE_RECORD_DATA_TTL:3}
# metricsDataTTL 作用于 metricsData,默认过期时间是 7 天
metricsDataTTL: ${SW_CORE_METRICS_DATA_TTL:7}

  上述配置可针对具体生产情况优化,建议都调大点。

忽略部分接口

  很多应用包中包含心跳请求,导致 APM 上传了很多不需要监控的路径,可以通过安装插件进行配置,以忽略这些路径减少上传分析的数据。

  相关插件为apm-trace-ignore-plugin-8.14.0.jar,因此我们若有相关需求可以使用:

1
cp optional-plugins/apm-trace-ignore-plugin-8.14.0.jar plugins/

  之后在agent/config下面新建一个配置文件apm-trace-ignore-plugin.config

1
vim apm-trace-ignore-plugin.config

  配置其内容为:

1
trace.ignore_path=${SW_AGENT_TRACE_IGNORE_PATH:/actuator/health/**,/eureka/**,Lettuce/**,Gson/**}

兼容 Spring Cloud Gateway

  若集成 Skywalking 的应用包含 Spring Cloud Gateway 组件,会发现 Gateway 模块无法加入到链路中。

  为什么呢?
  原因在于,Skywalking 默认情况下是不支持 Spring Cloud Gateway 组件的,那么,怎么让其支持呢?

  其实,skywalking-agent目录下存在两个插件目录:

  • pluginsskywalking-agent.jar在启动时会加载其下的所有 jar 包
  • optional-plugins:可选的插件 jar 包,skywalking-agent.jar在启动时不会加载其下 jar 包

  Skywalking 不支持 Gateway 的真实原因就在于,plugins目录下是没有相关支持的 jar 包的,但是!!!optional-plugins下是存在的,若想让 SkyWalking 支持 Gateway,只需要将可选插件下的相关 jar 包复制到plugins目录下即可。

1
2
3
4
5
# Spring Cloud Gateway 基于WebFlux实现,必须搭配上apm-spring-cloud-gateway-x.x.x-plugin 和 apm-spring-webflux-x.x-plugin 两个插件
# Gateway 版本不同,存在 2.x 和 3.x, 按自己版本选择即可
cp optional-plugins/apm-spring-cloud-gateway-3.x-plugin-8.14.0.jar plugins/

cp optional-plugins/apm-spring-webflux-5.x-plugin-8.14.0.jar plugins/

UI 兼容 Nginx

  默认的 Skywalking Web UI 不兼容 Nginx 子目录代理,需要重新编译源码包。
  从 Github 下载对应源码包后,修改vue.config.js,在module.exports中增加一行publicPath: "/skywalking",这个是前端部署在服务器上之后需要配置的子路径。但如果只修改这一行,部署之后会发现,前端要去请求一个graphql地址,这个地址不会被publicPath所影响,因此其请求的路径还是域名根路径,为了兼容这个,需要在代码中全局搜索/graphql,相关位置都改成/skywalking/graphql,然后使用编译打包丢到服务器上,之后进行 Nginx 配置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
location /skywalking {
allow 45.22.62.58;
deny all;
alias /data/frontend/skywalking;
try_files $uri $uri/ /skywalking/index.html;
}

location ^~ /skywalking/graphql {
allow 45.22.62.58;
deny all;
proxy_pass http://172.168.22.28:3080/graphql;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

参考

文章信息

时间 说明
2022-11-05 初版
0%