Skywalking学习笔记
概念
APM系统
apm(application performance Management)即应用性能管理系统,是对企业系统即时监控以实现对应用程序性能管理和故障管理的系统化的解决方案。应用性能管理,主要对企业的关键业务进行监测优化,提高企业应用的可靠性和质量,保证用户得到良好的服务,降低IT总拥有成本
AMP系统是可以帮助理解系统行为,用于分析性能问题,以便发生故障的时候,能够快速定位和解决问题
分布式链路追踪
随着分布式系统和微服务架构的出现,一次用户的请求会经过多个系统,不同服务之间的调用关系十分复杂,任何一个系统错误都可能影响整个请求的处理结果。以往的监控系统往往只能知道单个系统的健康情况,一次请求的成果失败,无法快速定位失败的根本原因
除此之外复杂的分布式系统也面临着这些问题
- 性能分担西,一个服务依赖很多服务,被依赖的服务也依赖的其他的服务。如果某个接口耗时突然变长了,那未必是下游服务变慢了,也可能是下游的下游变慢造成的,如何快速定位耗时变长的根本原因呢?
- 链路梳理,需求迭代很快,系统之间调用关系变化频繁,靠人工很难梳理清楚系统链路拓扑(系统之间的调用关系)
为了解决这些问题,google推出了一个分布式链路追踪系统Dapper,之后各个互联网公司都参照dapper的思想推出了自己的分布式链路跟踪系统,这些系统就是分布式系统下的APM系统
OpenTracing
分布式链路追踪最先由google在dapper论文中提出,而openTracing通过提供平台无关,厂商无关的API使得开发人员能够方便添加或更换追踪系统的实现。
比如有这样的订单调用关系图
它不能很好显示组件的调用时间,是串行还是并行调用,如果展现更复杂的调用关系,会更加复杂,甚至无法展现
这种图也无法显示调用时间的间隔以及是否通过定时调用来启动调用
基于openTracing我们就可以很容易的构建出上面这幅图
主流的APM产品
pinpoint
pinpoint是一个韩国团队实现并开源,针对java编写大规模分布式系统设计,通过javaAgent的机制做的字节码植入,实现traceid和获取性能数据的目的,对应用代码零侵入
SkyWalking
SkyWalking是apache基金会下面的一个开源APM项目,为微服务架构和云原生架构系统设计。它通过探针自动收集所需的指标,并进行分布式追踪。通过这些调用链路以及指标,Skywaling APM会感知应用关系和服务之间的关系,并进行响应的指标统计。Skywalking支持链路追踪和监控应用组件基本涵盖主流应用框架和容器如国产的RPC Doubbo和motan等,国际化springboot,springcloud
zipkin
aipkin是由推特开源是分布式链路调用监控系统,聚合各业务系统调用延迟数据,达到链路调用监控跟踪,zipkin基于google的dapper论文实现,主要完成数据收集,存储,搜索与界面展示
CAT
CAT是由大众点评的开源项目,基于java开发的实时应用监控平台,包括实时应用监控,业务监控,可以提供十几张报表展示
什么是Skywalking
简介
根据官方的解释,skywalking是一个可观测性分析平台(Observability analysis platform 简称APM)和应用性能管理系统(Application Performance Management简称APM)
下面是skywalking几大特点
- 多语言自动探针,java ,.net core和node.js
- 多种监控手段,语言探针,和service mesh
- 轻量高效。不需要额外搭建大数据平台
- 模块化架构。ui,存储集群管理多种可选机制
- 支持告警
- 优秀的可视化效果
skywalking提供tracing和metrices数据的获取和聚合
metric的特点是,它是可累加的:他们具有原子性,每个都是一个逻辑计量单元,或者一个时间段内的柱状图。例如:队列的当前深度可以被定义为一个计量单元,或者一个时间段内的柱状图。例如队列的当前深度可以被定义为一个计量单元,在写入或读取时被更新统计;输入的HTTP请求可以被定为一个计数器,用于简单的累加;请求的执行时间可以被定义为一个柱状图,在指定时间片上更新和统计汇总
tracing的最大特点就是,它在单词请求的范围内,处理信息。任何的数据,元数据信息都被绑定到系统的单个事物上。例如:一次远程调用服务的RPC执行过程;一次实际的SQL查询语句;一次HTTP请求的业务性
总结,Metric主要用来进行数据的统计,比如HTTP请求数的计算。Tracing主要包含了一次请求的链路数据
整体架构包含如下三个部分
- 探针(agent)负责进行数据的收集,包含了tracing和metrics的数据,agent会被安装到服务所在的服务器上,以方便数据的获取
- 可观测性分析平台OAP(Observability Analysis Platform) 接收探针发送的数据,并在内存中用分析引擎(Analysis core)进行数据的整合运算,然后将数据存储到对应的存储介质上,比如ElasticSearch,Mysql等数据库。同时OAP还使用查询引擎(Query Core)提供HTTP查询接口
- Skywalking提供单独的UI进行数据的查看,此时UI会调用OAP提供的接口,获取对应的数据然后进行展示
优势
- 社区活跃,支持语言多
- 探针无侵入性,不用修改原有代码
- 性能优秀
- 支持组件较多,特别是RPC框架的支持
主要概念
skywalking的主要概念包含
- 服务(service)
- 端点(Endpoint)
- 实例(Instance)
环境
搭建
Skywalkiong默认使用H2内存中进行数据的存储,我们可以替换存储源为ElasticSearch保存期查询的高效及可用性
安装skywalking分为俩个步骤
- 安装Backend后端服务
- 安装UI
解压skywalking-apm-bin安装包后有这样几个目录
探针 可执行文件 配置 ui安装包和配置
agent bin config LICENSE licenses NOTICE oap-libs README.txt webapp
打开config下的application.yml文件
打开被注释掉的ES配置项,把h2的给注释掉
然后打开webapp文件夹,编辑webapp.yml文件(这个webapp中本质上其实是一个springboot应用)
最后打开bin目录,通过startup.sh把这俩个(OAP和webapp)应用都启动
这时候目录下就会出现logs文件夹
tail -f -webapp.log
查看启动情况
然后访问对应的端口就可以进行访问了
Agent
agent探针可以让我们不修改代码的情况下,对java应用上使用到的组件进行动态监控,获取运行数据发送到OAP上进行存储。agent探针在java中是使用java agent技术实现的,不需要更改任何代码,java agent会通过虚拟机接口在运行期更改代码
打开agent目录有
- activations
- bootstrap-pluging
- config:配置文件
- logs:日志文件
- opional-plugins:可选插件
- plugins:组件的所有插件
- skywalking-agent.jar
部分插件在使用上会影响整体性能或者由于版权问题放置在可选插件包中,不会直接加载,如要要使用将可选插件中的jar包拷贝到plugins包下
打开config/agent.config
由于没有修改探针中的应用名默认显示的是Your_ApplicationName,我们修改下应用名称
找到
agent.service_name=${SW_AGENT_NAME:skywalking_tomcat}
然后重启,(SW_AGENT_NAME这个指的是环境变量中的这个值,如果环境变量有就会优先用这个值)
tomcat使用
使用skywalking监控tomcat中的应用,先要准备一个springmvc的项目
打开tomcat的bin目录下编辑catalina.sh文件
在文件顶部添加
CATALINA_OPTS="$CATALINA_OPTS -javaagent:/usr/local/skywalking/apache-skying-apm-bin/agent/skywlking-agent.jar"; export CATALINA_OPTS
配置好了访问其中一个接口就显示
当前服务下显示的就是之前修改的服务名,这是拓补图
可以在追踪中看到详细信息
windows下tomcat目录/bin/catalina.bat文件第一行为
set "CATALINA_OPTS=-javaagent:/path/to/skywalking-agent/skywalking-agent.jar"
Srpingboot中使用
修改完skywalking服务名后
使用命令启动springboot项目
java -javaagent /usr/local/skywaking/apache-skywalking-apm-bin/agent_boot/skywalking-agent.jar -Dserver.port=8082 -jar skywlking_springboot.jar &
使用jar包启动的项目如果要集成skywalking,需要添加-javaagent参数,参数值为agent的jar包位置
启动的过程大同小异,主要是在启动命令中加一个agent探针
dubbo也是相似,dubbo配置之后会出现这样的调用链
常用插件
配置覆盖
在之前的案例中,我们每次部署都需要复制一份agent,修改其中的服务名称,这样显得非常麻烦。可以用skywalking提供的配置覆盖功能通过启动命令动态指定服务名称,这样agent只需要部署一份即可,Skywalking支持几种配置方式
系统配置(System properties)
使用skywlking.+配置文件中的配置名称作为系统配置项来进行覆盖
为什么要添加前缀?
agent的系统配置和环境与目标应用共享,所以加上前缀可以有效的避免冲突
如果如下进行agent.service_name覆盖
-Dskywlaking.agent.service_name=skywalking_mysql
探针配置(Agent options)
例如通过如下进行agent.service_name的覆盖
-javaagent:/path/to/skywaking-agent.jar=agent.service_name=skywaking_mysql
特殊字符
如果配置中包含风格符(,或者=)就必须使用引号包裹起来
系统环境变量(System environment variables)
案例
可以在环境变量中设置SW_AGENT_NAME来指定服务名
覆盖优先级
探针配置>系统配置>系统环境变量>配置文件中的值
获取追踪ID
集成后可以直接在接口中获取到追踪ID
包括在其中输入错误信息
过滤指定的端点
在开发过程中有些断点不需要进行监控,比如Swagger相关端点.这时候我们就可以使用Skywalking提供的过滤插件来进行过滤.在Skywalking_plugins中编写俩个接口进行测试
将skwalking_plugins.jar上传到/usr/local/skywalking目录下
将agent中的/agent/optional-plugins/apm-trace-ignore-plugin-6.4.0拷贝到plugins目录中
添加
-Dskywaking.trace.ignore_path=/exclude
表示要过滤的请求,支持path表达式
/path/,/path/*,/path/?
?匹配单个字符
*或者0匹配任意数量的字符
启动skywaking_plugins应用
告警功能
Skywalking每隔一段时间根据收集到的链路追踪数据和配置的告警规则(如服务响应时间,服务响应时间百分比)等,判断如果达到阈值则发送相应的告警信息.
发送告警信息可是通过webhook接口完成,具体的webhook接口可以使用者自行定义,从而开发者可以在指定的webhook接口中编写各种告警方式,比如邮件,短信等.告警信息也可以在RocketBot中查看到
Skywalking安装目录下的config文件夹下游alarm-setting.yml文件
修改告警地址为自己的地址
webhooks:
- http://127.0.0.1/notify
skywaking就会通过这个接口传递到系统中进行告警
kywalking中有一些默认的告警规则,如下:
- 最近3分钟内服务的平均响应时间超过1秒
- 最近2分钟服务成功率低于80%
- 最近3分钟90%服务响应时间超过1秒
- 最近2分钟内服务实例的平均响应时间超过1秒
当然除了以上四种,随着Skywalking不断迭代也会新增其他规则,这些规则的配置在config/alarm-settings.yml
配置文件中
每个规则都由相同的属性组成,这些属性的含义如下图:
如果想要调整默认的规则,比如监控返回的信息,监控的参数等等,只需要改动上述配置文件中的参数即可。
当然除了以上默认的几种规则,skywalking还适配了一些钩子(webhooks)。其实就是相当于一个回调,一旦触发了上述规则告警,skywalking则会调用配置的webhook,这样开发者就可以定制一些处理方法
当然这个钩子也是有些规则的,如下:
- POST请求
- application/json 接收数据
- 接收的参数必须是AlarmMessage中指定的参数。
注意:AlarmMessage这个类随着skywalking版本的迭代可能出现不同,一定要到对应版本源码中去找到这个类,拷贝其中的属性。这个类在源码的路径:org.apache.skywalking.oap.server.core.alarm
,如下图:
java agent原理
上文中我们知道,要是用Skywalking去监控服务,需要在VM参数添加
-javaagent:/path/to/skywalking-agent/skywalking-agent.jar
这里就使用到了java agent技术
javaagent是什么
java agent是java命令的一个参数。参数javaagent可以指定一个jar包
- 这个jar包的MANIFEST.MF文件必须指定Premain-Class项
- Premain-Class指定的那个类必须实现premain()方法
当java虚拟机启动时,在执行main函数之前,JVM会先运行-javaagent所指定jar包内premain-Class这个类的premain方法。
如何使用java agent?
- 定义MANIFEST.MF文件,必须包含Premain-Class选项,通常也会加入Can-Readfine-Classes和CanRetransform-Class选项
- 创建一个Premain-Class指定的类,类中包含premain方法,方法逻辑由用户自己定义
- 将premain的类和MANIFEST.MF文件打成jar包。
- 使用参数-javaagent:jar包路径启动要代理的方法
可以使用maven-assembly-plugin打包
会有限调用更多参数的premain方法
统计方法调用
ByteBuddy是一个字节码增强框架,是底层基于ASM技术
ByteBuddy和是开源的,基于apche2.0库的许可证。ByteBuddy所声称的目标是将显式的字节码操作,隐藏在一个类安全的领域特定语言背后。通过ByteBuddy,任何熟悉java编程语言的人都有望非常容易的进行字节码操作。ByteBBuddy提供了额外的API来生成Java agent,可以轻松增加我们已有的代码
之前需要统计调用和访问的话必须要用到AOP技术
OpenTracing
之前的描述中见到介绍过OpenTracing这个概念,OpenTracing通过提供平台无关,厂商无关的API,使得开发人员能够方便的添加(或更换)追踪的实现,OpenTracing,OpenTracing最核心的概念技术trace
Trace
在广义上trace代表了一个事物或者流程在(分布式)系统的执行过程。在OpenTracing标准中,trace是多个span组成的一个有向无环图(DAG),每一个span代表trace中被命名计时的连续性执行片段
例如客户端发起的每一次请求,都可以认为是一个trace。将上面的图通过OpenTracing的语义修改完成后做可视化得到下面的图
图中每一个色块就是一个span
span
一个span代表系统中具有开始时间和执行时长的逻辑运行单元。span之间通过嵌套护着顺序排列简历逻辑因果关系。span里面的信息包括:操作的名字,开始时间和结束时间,可以附带多个可以附带多个key:value构成tags(key必须是string,value可以是string,bool或者数字),还可以附带logs信息(不一定所有都实现都支持)也是key:value的形式
一个span可以和一个或者多个span之间存在因果关系。OpenTracing定义了俩种关系:ChildOf和FollowsFrom。这俩种引用类型代表了子节点和父节点之间的直接因果关系。未来OpenTracing将支持非因果关系的span引用关系(例如多个span被批量处理,span在同一个队列中等)
childOf很好理解,就是父亲span依赖另一个孩子span。比如函数调用,被调用者是调用者的孩子,比如说RPC调用,服务端那边的span,就是childOf客户端的。很多并发的调用,然后将结果聚合起来的操作就构成了ChildOf关系
如果父亲span不依赖于孩子span的返回结果,这时可以说他构成FollowsFrom关系
如图所示左边每一条追踪代表一个trace,右边中每一个节点计就是一个span
log
每个span可以进行多次logs操作,每一次logs操作都需要一个带时间戳的时间名称,以及可选的任意大小的存储结构
如下图是一个异常的Log
如下图是俩个正常信息的log,它们都带有时间戳和对应的事件名称,消息内容
tags
每个span可以有多个键值对(key:value)形式tags,tags是没有时间戳的,支持简单的对span进行注解和补充
如下图就是一个Tags的详细信息,记录了数据库访问sql语句等内容
如下图就是一个tags的详细信息,其中记录了数据访问的sql等内容