微服务链路追踪SkyWalking
Posted mry6
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了微服务链路追踪SkyWalking相关的知识,希望对你有一定的参考价值。
微服务链路追踪SkyWalking
链路追踪介绍
对于一个大型的几十个、几百个微服务构成的微服务架构系统,通常会遇到下面一些问题,比如:
(1) 如何串联整个调用链路,快速定位问题?
(2) 如何缕清各个微服务之间的依赖关系?
(3) 如何进行各个微服务接口的性能分析?
(4) 如何跟踪整个业务流程的调用处理顺序?
skywalking是什么
skywalking是一个国产开源框架,2015年由吴晟开源,2017年加入Apache孵化器。skywalking是分布式系统的应用程序性能监视工具,专为微服务、云原生架构和基于容器(Docker、K8s、Mesos)架构而设计。它是一款优秀的APM(Application Performance Management)工具,包括了分布式追踪、性能指标分析、应用和服务依赖分析等。
官网:http://skywalking.apache.org/
下载:http://skywalking.apache.org/downloads/
Github:http://github.com/apache/skywalking
文档:http://skywalking.apache.org/docs/main/v8.4.0/readme/
中午文档:http://skyapm.github.io/document-cn-translation-of-skywalking/
1.链路追踪框架对比
(1) Zipkin是Twitter开源的调用链分析工具,目前基于springcloud sleuth得到了广泛的使用,特点是轻量,使用部署简单。
(2) Pinpoint是韩国人开源的基于字节码注入的调用链分析,以及应用监控分析工具,特点是支持多种插件,UI功能强大,接入端无代码侵入。
(3) SkyWalking是本土开源的基于字节码注入的调用链分析,以及应用监控分析工具,特点是支持多种插件,UI功能较强,接入端无代码侵入。 目前已加入Apache孵化器。
(4) CAT是大众点评开源的基于编码和配置的调用链分析,应用监控分析,日志采集,监控报警等一系列的监控平台工具。
2.基本原理
项目 | CAT | Zipkin | SkyWalking |
---|---|---|---|
调用链可视化 | 有 | 有 | 有 |
聚合报表 | 非常丰富 | 少 | 较丰富 |
服务依赖图 | 简单 | 简单 | 好 |
埋点方式 | 侵入式 | 侵入式 | 非侵入,字节码增强 |
VM监控指标 | 好 | 无 | 有 |
支持语言 | java/.net | 丰富 | java/.net/Nodejs/php/go |
存储机制 | mysql(报表)、本地文件/HDFS(调用链) | 内存、es、mysql等 | H2、es |
社区支持 | 主要在国内 | 国外主流 | Apache支持 |
使用案例 | 美团、携程、陆金所 | 京东、阿里定制后不开源 | 华为、小米、当当、微众银行 |
APM | 是 | 否 | 是 |
开发基础 | eBay | Google Dapper | Google Dapper |
是否支持webflux | 否 | 是 | 是 |
Github stars(2019.12) | 12.3K | 12.2K | 11.8K |
3.性能对比
模拟了三种并发用户:500,750,1000。使用jmeter测试,每个线程发送30个请求,设置思考时间为10ms。使用的采用率为1,即100%,这边与生产可能有差别。pinpoint默认的采样率为20,即50%,通过设置agent的配置文件改为100%。zipkin默认也是1。组合起来,一共有12种。下面看下汇总表:
从上表可以看出,在三种链路监控组件中,skywalking的探针对吞吐量的影响最小,zipkin的吞吐量居中。pinpoint的探针对吞吐量的影响较为明显,在500并发用户时,测试服务的吞吐量从1385降低到774,影响很大。然后再看下CPU和memory的影响,在内部服务器进行的压测,对CPU和memory的影响都差不多在10%之内。
4.SkyWalking主要功能特性
(1) 多种监控手段,可以通过语言探针和service mesh获得监控的数据;
(2) 支持多种语言自动探针,包括Java、.Net Core 和 Node.js;
(3) 轻量高效,无需大数据平台和大量的服务器资源;
(4) 模块化。UI、存储、集群管理都有多种机制可选;
(5) 支持告警;
(6) 优秀的可视化解决方案;
SkyWalking环境搭建部署
(1) SkyWalking agent和业务系统绑定在一起,负责收集各种监控数据
(2) SkyWalking oapservice是负责处理监控数据的,比如接受SkyWalking agent的监控数据,并存储在数据库中;接受SkyWalking webapp的前端请求,从数据库查询数据,并返回数据给前端。SkyWalking oapservice通常以集群的形式存在。
(3) SkyWalking webapp,前端界面,用于展示数据。
(4) 用于存储监控数据的数据库,比如mysql、elasticsearch等。
1.下载SkyWalking
下载地址:http://skywalking.apache.org/downloads/
目录结构:
1》webapp:UI前端(web监控页面)的jar包和配置文件;
2》oap-libs:后台应用的jar包,以及它的依赖jar包,里边有一个server-starter-.jar就是启动程序;
3》config:启动后台应用程序的配置文件,是存放应用的各种配置
4》bin:各种启动脚本,一般使用脚本startup.来启动web页面和对应的后台应用;
(1) oapService.:默认使用的后台程序的启动脚本;(使用的是默认模式启动,还支持其他模式,各模式区别见启动模式)
(2) oapServiceInit.:使用init模式启动;在此模式下,OAP服务器启动以执行初始化工作,然后退出
(3) oapServiceNoInit.:使用no init模式启动;在此模式下,OAP服务器不进行初始化。
(4) webappService.:UI前端的启动脚本;
(5) startup.:组合脚本,同时启动oapService.、webappService.*脚本;
5》agent
(1) skywalking-agent.jar:代理服务jar包
(2) config:代理服务启动时使用的配置文件
(3) plugins:包含多个插件,代理服务启动时会加载该目录下的所有插件(实际是各种jar包)
(4) optional-plugins:可选插件,当需要支持某种功能时,比如SpringCloud Gateway,则需要把对应的jar包拷贝到plugins目录下;
2.搭建SkyWalking OAP服务
1》启动脚本
bin/startup.sh
2》日志信息存储在logs目录
3》启动成功后会启动两个服务,一个是skywalking-oap-server,一个是skywalking-web-ui
skywalking-oap-server服务启动后会暴露11800和12800两个端口,分别为收集监控数据的端口11800和接受前端请求的端口12800,修改端口可以修改config/application.yml
4》skywalking-web-ui服务会占用8080端口,修改端口可以修改webapp/webapp.yml
5》浏览web页面:http://localhost:8868/
页面的右下角可以中英文切换,可以切换选择要展示的时间区间的跟踪数据。
3.SkyWalking中三个概念
服务(Service):表示对请求提供相同行为的一系列或一组工作负载,在使用Agent时,可以定义服务的名字;
服务实例(Service Instance):上述的一组工作负载中的每一个工作负载称为一个实例,一个服务实例实际就是操作系统上的一个真实进程;
端点(Endpoint):对于特定服务所接收的请求路径,如HTTP的URL路径和gRPC的服务的类名 + 方法签名;
SkyWalking跨多个微服务跟踪
SkyWalking跨多个微服务跟踪,只需要每个微服务启动时添加javaagent参数即可。
测试:
启动微服务api-gateway、alibaba-order-seata、alibaba-stock-seata,配置skywalking的jvm参数
-javaagent:D:\\server\\apache-skywalking-apm-bin-es7\\agent\\skywalking-agent.jar
-DSW_AGENT_NAME=alibaba-stock-seata
-DSW_AGENT_COLLECTOR_BACKEEND_SERVICES=127.0.0.1:11800
请求地址:http://localhost:8088/order/add
SkyWalking UI介绍
SkyWalking UI页面功能
1.菜单栏
仪表盘:查看被监控服务的运行状态;
拓扑图:以拓扑图的方式展现服务之间的关系,并以此为入口查看相关信息;
追踪:以接口列表的方式展现,追踪接口内部调用过程;
性能剖析:对端点进行采样分析,并可查看堆栈信息;
告警:触发告警的告警列表,包括服务失败率,请求超时等;
自动刷新:刷新当前页面数据内容;
2.控制栏
第一栏:不同内容主题的监控面板,应用性能管理/数据库/容器等;
第二栏:操作,包括编辑/导出当前数据/倒入展示数据/不同服务端点筛选展示;
第三栏:不同维度展示,全局/服务/实例/端点;
3.展示栏
Global全局维度
第一栏:Global、Service、Instance、Endpoint不同展示版面;
Service load:服务每分钟请求数;
Slow Service:慢响应服务,单位ms;
Un-Health Services(Apdex):Apdex性能指标,1为满分;
Slow Endpoint:慢响应端点,单位ms;
Global Response Latency:百分比响应延时,不同百分比的延时时间,单位ms;
Global Heatmap:服务响应时间热力分布图,根据时间段内不同响应时间的数量显示颜色深度;
底部栏:展示数据的时间区间,点击可以调整;
4.Service服务维度
Service Apdex(数字):当前服务的评分;
Service Apdex(折线图):不同时间的Apdex评分;
Service Avg Response Times:平均响应延时,单位ms;
Service Response Time Percentile:百分比响应延时;
Successful Rate(数字):请求成功率;
Successful Rate(折线图):不同时间的请求成功率;
Service Load(数字):每分钟请求数;
Service Load(折线图):不同时间的每分钟请求数;
Service Instances Load:每个服务实例的每分钟请求数;
Show Service Instance:每个服务实例的最大延时;
Service Instance Successful Rate:每个服务实例的请求成功率;
5.Instance服务维度
Service Instance Load:当前实例的每分钟请求数;
Service Instance Successful Rate:当前实例的请求成功率;
Service Instance Latency:当前实例的响应延时;
JVM CPU:jvm占用CPU的百分比;
JVM Memory:JVM内存占用大小,单位m;
JVM GC Time:JVM垃圾回收时间,包含YGC和OGC;
JVM GC Count:JVM垃圾回收次数,包含YGC和OGC;
JVM Thread Count:JVM线程数;
还有几个是.NET的,类似于JVM虚拟机,暂时不做说明;
6.Endpoint端点(API)维度
Endpoint Load in Current Service:每个端点的每分钟请求数;
Slow Endpoint in Current Service:每个端点的最慢请求时间,单位ms;
Successful Rate in Current Service:每个端点的请求成功率;
Endpoint Load:当前端点每个时间段的请求数据;
Endpoint Avg Response Time:当前端点每个时间段的请求行响应时间;
Endpoint Response Time Percentile:当前端点每个时间段的响应时间占比;
Endpoint Successful Rate:当前端点每个时间段的请求成功率;
7.拓扑图
1》选择不同的服务关联拓扑图;
2》查看单个服务相关内容;
3》服务间连接情况;
4》分组展示服务拓扑;
8.追踪
左侧:api接口列表,红色-异常请求,蓝色-正常请求;
右侧:api追踪列表,api请求连接各端点的先后顺序和时间;
SkyWalking接入微服务
1.Linux环境 – 通过jar包方式接入
准备一个springboot程序,打成可执行jar包,写一个shell脚本,在启动项目的shell脚本上,通过 -javaagent参数进行配置SkyWalking Agent来跟踪微服务;
startup.sh脚本:
#! /bin/sh
# SkyWalking Agent配置
export SW_AGENT_NAME=springboot-skywalking-demo # Agent名字,一般使用'spring.application.name'
export SW_AGENT_COLLECTOR_BACKEND_SERVICES=127.0.0.1:11800 #配置Collector地址
export SW_AGENT_SPAN_LIMIT=2000 #配置链路的最大Span数量,默认为300
export JAVA_AGENT=-javaagent:/usr/local/soft/apache-skywalking-apm-bin-es7/agent/skywalking-agent.jar
java $JAVA_AGENT -jar springboot-skywalking-demo-0.0.1-SNAPSHOT.jar #jar启动
启动日志:
等同于:
java -javaagent:/usr/local/soft/apache-skywalking-apm-bin-es7/agent/skywalking-agent.jar
-DSW_AGENT_COLLECTOR_BACKEND_SERVICES=127.0.0.1:11800
-DSW_AGENT_NAME=springboot-skywalking-demo -jar springboot-skywalking-demo-0.0.1-SNAPSHOT.jar
参数名对应agent/config/agent.config配置文件中的属性。
属性对应的源码:org.apache.skywalking.apm.agent.core.Config.java
# The service name in UI
agent.service_name=$SW_AGENT_NAME:Your_ApplicationName
# Backend service addresses.
collector.backend_service=$SW_AGENT_COLLECTOR_BACKEND_SERVICES:127.0.0.1:11800
我们也可以使用skywalking+配置文件中的配置名作为系统配置来进行覆盖。javaagent参数配置方式优先级更高
2.Windows环境 – 在IDEA中使用SkyWalking
在运行的程序配置jvm参数;如下图所示:
# skywalking-agent.jar的本地磁盘的路径
-javaagent:D:\\server\\apache-skywalking-apm-bin-es7\\agent\\skywalking-agent.jar
# 在skywalking上显示的服务名
-DSW_AGENT_NAME=springboot-skywalking-demo
# skywalking的collector服务的IP及端口
-DSW_AGENT_COLLECTOR_BACKEND_SERVICES=127.0.0.1:11800
-DSW_AGENT_COLLECTOR_BACKEND_SERVICES 可以指定远程地址,但是-javaagent必须绑定你本机物理路径的skywalking-agent.jar
注意:此处存在bug,跟踪链路不显示gateway
拷贝agent/optional-plugins目录下的gateway插件到agent/plugins目录下
SkyWalking持久化跟踪数据
默认使用的H2数据库存储
config/application.yml
1.基于mysql持久化
1》修改config目录下的application.yml,使用mysql作为持久化存储的仓库
2》修改mysql连接配置
3》新建swtest数据库,swtest数据库中的表会在SkyWalking启动时自动生成
4》启动SkyWalking服务
启动时报下面异常:
原因:因为oap-libs中没有jdbc驱动jar包。
解决方法:在oap-libs文件夹中添加jdbc驱动jar包(mysql-connector-java-8.0.21.jar).
自定义SkyWalking链路追踪
如果我们希望对项目中的的业务方法,实现链路追踪,方便我们排查问题,可以使用如下的代码
引入依赖:
<!--skywalking 工具类-->
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-trace</artifactId>
<version>8.5.0</version>
</dependency>
1.@Trace将方法加入追踪链路
如果一个业务方法想在ui界面的跟踪链路上显示出来,只需要在业务方法上加上@Trace注解即可
@Override
@Trace
public List<Order> all() throws InterruptedException
TimeUnit.SECONDS.sleep(2);
return orderMapper.selectAll();
测试:
2.加入@Tags或@Tag
我们还可以为追踪链路增加其他额外的信息,比如记录参数和返回信息。实现方式:在方法上增加@Tag或者@Tags。
@Service
public class OrderServiceImpl implements OrderService
@Autowired
OrderMapper orderMapper;
@Override
@Trace
@Tag(key = "getAll", value = "returnedObj")
public List<Order> all() throws InterruptedException
TimeUnit.SECONDS.sleep(2);
return orderMapper.selectAll();
@Override
@Trace
@Tags(@Tag(key = "param", value = "arg[0]"),
@Tag(key = "get", value = "returnedObj"))
public Order get(Integer id)
return orderMapper.selectByPrimaryKey(id);
测试:
性能分析
SkyWalking的性能分析,在根据服务名称、端点名称,以及相应的规则建立了任务列表后,在调用了此任务列表的端点后。SkyWalking会自动记录,剖析当前端口,生成剖析结果,具体流程如图:
SkyWalking集成日志框架
引入依赖
<!--apm-toolkit-logback-1.x-->
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-logback-1.x</artifactId>
<version>8.5.0</version>
</dependency>
添加logback-spring.xml文件,并配置[%tid]占位符
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 引入Spring Boot 默认的logback XML 配置文件-->
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<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>-%clr(%d$LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS)faint %clr($LOG_LEVEL_PATTERN:-%5p) %clr($PID:- )magenta [%tid] %clr(---)faint %clr([%15.15t])faint %clr(%-40.40logger39)cyan %clr(:)faint %m%n$LOG_EXCEPTION_CONVERSION_WORD:-%wEx</Pattern>
</layout>
</encoder>
</appender>
<!-- 设置Appender-->
<root level="INFO">
<appender-ref ref="console"/>
</root>
</configuration>
SkyWalking通过grpc上报日志(需要v8.4.0+)
gRPC报告程序可以将收集到的日志转发到SkyWalking OAP服务器上
logback-spring.xml中添加:
<!--v8.4.0提供-->
<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>%dyyyy-MM-dd HH:mm:ss.SSS [%Xtid] [%thread] %-5level %logger36 -%msg%n</Pattern>
</layout>
</encoder>
</appender>
<!-- 设置Appender-->
<root level="INFO">
<appender-ref ref="console"/>
<appender-ref ref="grpc-log"/>
</root>
打开agent/config/agent.config配置文件,添加如下配置信息:
plugin.toolkit.log.grpc.reporter.server_host=$SW_GRPC_LOG_SERVER_HOST:127.0.0.1
plugin.toolkit.log.grpc.reporter.server_port=$SW_GRPC_LOG_SERVER_PORT:11800
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
以上配置是默认配置信息,agent与oap在本地的可以不配
配置名 | 解释 | 默认值 |
---|---|---|
plugin.toolkit.log.transmit_formatted | 是否以格式化或未格式化的格式传输记录的数据 | true |
plugin.toolkit.log.grpc.reporter.server_host | 指定要向其报告日志数据的grpc服务器的主机 | 127.0.0.1 |
plugin.toolkit.log.grpc.reporter.server_port | 指定要向其报告日志数据的grpc服务器的端口 | 11800 |
plugin.toolkit.log.grpc.reporter.max_message_size | 指定grpc客户端要报告的日志数据的最大大小 | 10485760 |
plugin.toolkit.log.grpc.reporter.upstream_timeout | 客户端向上游发送数据时将超时多长时间。单位是秒 | 30 |
Skywalking UI效果:
SkyWalking告警功能
SkyWalking告警功能是在6.x版本新增的,其核心由一组规则驱动,这些规则定义在config/alarm-setting.yml文件中,告警规则的定义分为两部分:
1》告警规则:它们定义了应该如何触发度量警报,应该考虑什么条件。
2》Webhook(网络钩子):定义当警告触发时,哪些服务端需要被告知
1.告警规则
SkyWalking的发行版都会默认提供config/alarm-setting.yml文件,里面预先定义了一些常用的告警规则,如下:
1》过去3分钟内服务平均响应时间超过1秒。
2》过去2分钟服务成功率低于80%。
3》过去3分钟内服务响应时间超过1s的百分比。
4》服务实例在过去2分钟内平均响应时间超过1s,并且实例名称与正则表达式匹配。
5》过去2分钟内端点平均响应时间超过1秒。
6》过去2分钟内数据库访问平均响应时间超过1秒。
7》过去2分钟内端点关系平均响应时间超过1秒。
这些预定义的告警规则,打开config/alarm-setting.yml文件即可看到
告警规则配置项的说明:
1》Rule name:规则名称,也是在告警信息中显示的唯一名称,必须以_rule结尾,前缀可自定义
2》Metrics name:度量名称,取值为oal脚本中的度量名,目前只支持long、double和int类型。详见Official OAL script
3》Include names:该规则作用于哪些实体名称,比如服务名,终端名(可选,默认为全部)
4》Exclude names:该规则作不用于哪些实体名称,比如服务名,终端名(可选,默认为全部)
5》Threshold:阈值
6》OP:操作符,目前支持>,<,=
7》Period:多久警告规则需要被核实一下,这是一个时间窗口,与后端部署环境时间相匹配
8》Count:在一个Period窗口中,如果values超时Threshold值(按op),达到Count值,需要发送警报
9》Sitence period:在时间N中触发报警后,在TN -> TN + period这个阶段不告警。默认情况下,它和Period一样,这意味着看相同的告警(在同一个Metrics name拥有相同的id)在同一个Ponod内只会触发一次
10》message:告警信息
Webhook(网络钩子)
Webhook可以简单理解为是一种Web层面的回调机制,通常由一些事件触发,与代码中的事件回调类似,只不过是Web层面的。由于是Web层面的,所以当事件发生时,回调的不再是代码中的方法或函数,而是服务接口。例如,在警告这个场景,警告就是一个事件,当该事件发生时,SkyWalking就会主动去调用一个配置好的接口,该接口就是所谓的Webhook。
SkyWalking的告警消息会通过HTTP请求进行发送,请求方法为POST,Content-Type为application/json,其JSON数据是基于List<org.apache.skywalking.oap.server.core.alarm.AlarmMessage>进行序列化的。JSON数据示例:
[
"scopeId": 1,
"scope": "SERVICE",
"name": "serviceA",
"id0": "12",
"id1": "",
"ruleName": "service_resp_time_rule",
"alarmMessage": "alarmMessage xxxx",
"startTime": 1560524171000
,
"scopeId": 1,
"scope": "SERVICE",
"name": "serviceB",
"id0": "23",
"id1": "",
"ruleName": "service_resp_time_rule",
"alarmMessage": "alarmMessage yyy",
"startTime": 1560524171000
]
字段说明:
1》scopeld、scope:所有可用的Scope详见org.apache.skywalking.oap.server.core.source.DefaultScopeDefine
2》name:目标Scope的实体名称
3》Id0:Scope实体的ID
4》Id1:保留字段,目前暂未使用
5》ruleName:告警规则名称
6》alarmMessage:告警消息内容
7》startTime:告警时间,格式为时间戳
告警信息在项目日志中输出
1.在config/alarm-setting.yml中添加请求地址
2.SwAlarmDTO实体类
public class SwAlarmDTO
private int scopeId;
private String scope;
private String name;
private String id0;
private String id1;
private String ruleName;
private String alarmMessage;
以上是关于微服务链路追踪SkyWalking的主要内容,如果未能解决你的问题,请参考以下文章
Spring Cloud Alibaba全家桶——微服务链路追踪SkyWalking
Kubernetes + Spring Cloud 集成链路追踪 SkyWalking