当前位置: 首页 > article >正文

SkyWalking快速入门

参考课程:2023深入理解SkyWalking微服务链路追踪实战_哔哩哔哩_bilibili

SkyWalking 主要用于分布式系统的性能监控和故障排查,它通过收集和分析各个服务之间的调用关系、性能指标等数据,帮助开发者和运维人员快速了解系统的运行状态,定位性能瓶颈和故障。常用于用户指标分析,性能指标分析,告警功能,服务依赖关系可视化


SkyWalking相关概念

基本了解

分布式调用链标准-openTracing

Span-节点

跟踪树结构

不同系统之间RPC,HTTP,MQ之间的调用是有区别的,那我们应该如何区分这些数据呢?

有一些特定的变量,SpanName SpanId traceId spanParentId

植入点:我们监控的地方,我们要尽可能零侵入进行代码采集

采样率:采集我们的信息,为了知道哪里出现了问题从而尽可能提升性能


Opentracing标准详解

我们要根据规范来设计我们的Tag的key和value

一个调用链是由多个Span组成的,span和span之间的关系是reference(调用)

标准调用结构图

分为父子关系和兄弟关系

父子关系是A和B,C

兄弟关系是F,G,H,我们按照顺序来进行调用,先F然后G然后H

Span节点必须包含的东西

OperationName:操作名称

BeiginTime:开始时间

EndTime:结束时间

SpanTag:是一组键值对构成的Span的标签集合(key必须是String类型,value可以是String,Boolean和数字类型),这个的目的是为Span添加更多的描述信息

SpanLog:一组Span的日志集合,是键值对,记录日志信息

SpanContext:是一个上下文对象,会从上一个节点传递到下一个节点,里面包含了traceIdSpanIdBaggage(这是一个跨Span集合,上一个节点往Baggage加信息下一个节点可以拿到,不要放太多信息不然会导致占用空间大影响效率),我们通过上下文对象去进行跨进程传递


OpenTacingApi

opentracing-specification-zh/specification.md at master · opentracing-contrib/opentracing-specification-zh · GitHub

一些基本API的使用


Tracer接口

Tracer接口用来创造Span,以及如何处理Inject和Extract,用于跨进行边界传递

创建一个新的Span

必填参数:OperationName,操作名

可选参数:

  • 零个或者多个关联(references)的SpanContext,如果可能,同时快速指定关系类型,ChildOf 还是 FollowsFrom
  • 一个可选的显性传递的开始时间BeginTime;如果忽略,当前时间被用作开始时间。
  • 零个或者多个tag

返回值,返回一个已经启动Span实例(已启动,但未结束。译者注:英语上started和finished理解容易混淆)

SpanContext上下文Inject(注入)到carrier

必填参数

  • SpanContext 实例
  • format(格式化)描述,一般会是一个字符串常量,但不做强制要求。通过此描述,通知Tracer实现,如何对SpanContext进行编码放入到carrier中。
  • carrier,根据format确定。Tracer实现根据format声明的格式,将SpanContext序列化到carrier对象中

SpanContext上下文从carrier中Extract(提取)

必填参数

  • format(格式化)描述,一般会是一个字符串常量,但不做强制要求。通过此描述,通知Tracer实现,如何从carrier中解码SpanContext
  • carrier,根据format确定。Tracer实现根据format声明的格式,从carrier中解码SpanContext

返回值,返回一个SpanContext实例,可以使用这个SpanContext实例,通过Tracer创建新的Span

注意,对于Inject(注入)和Extract(提取),format是必须的

Inject(注入)和Extract(提取)依赖于可扩展的format参数。format参数规定了另一个参数"carrier"的类型,同时约束了"carrier"中SpanContext是如何编码的。所有的Tracer实现,都必须支持下面的format

  • Text Map: 基于字符串:字符串的map,对于key和value不约束字符集。
  • HTTP Headers: 适合作为HTTP头信息的,基于字符串:字符串的map。(RFC 7230.在工程实践中,如何处理HTTP头具有多样性,强烈建议tracer的使用者谨慎使用HTTP头的键值空间和转义符)
  • Binary: 一个简单的二进制大对象,记录SpanContext的信息

Span

Span结束后(span.finish()),除了通过Span获取SpanContext外,下列其他所有方法都不允许被调用

获取SpanSpanContext

不需要任何参数。

返回值Span构建时传入的SpanContext。这个返回值在Span结束后(span.finish()),依然可以使用

复写操作名(operation name)

必填参数

  • 新的操作名operation name,覆盖构建Span时,传入的操作名。

结束Span

可选参数

  • 一个明确的完成时间;如果省略此参数,使用当前时间作为完成时间。

Span设置tag

必填参数

  • tag key,必须是string类型
  • tag value,类型为字符串,布尔或者数字

注意,OpenTracing标准包含**"standard tags,标准Tag"**,此文档中定义了Tag的标准含义。

Log结构化数据

必填参数

  • 一个或者多个键值对,其中键必须是字符串类型,值可以是任意类型。某些OpenTracing实现,可能支持更多的log值类型。

可选参数

  • 一个明确的时间戳。如果指定时间戳,那么它必须在span的开始和结束时间之内。

注意,OpenTracing标准包含**"standard log keys,标准log的键"**,此文档中定义了这些键的标准含义

设置一个baggage(随行数据)元素

Baggage元素是一个键值对集合,将这些值设置给给定的SpanSpanSpanContext,以及所有和此Span有直接或者间接关系的本地Span 也就是说,baggage元素随trace一起保持在带内传递。(译者注:带内传递,在这里指,随应用程序调用过程一起传递)

Baggage元素具有强大的功能,使得OpenTracing能够实现全栈集成(例如:任意的应用程序数据,可以在移动端创建它,显然的,它会一直传递了系统最底层的存储系统),同时他也会产生巨大的开销,请小心使用此特性。

再次强调,请谨慎使用此特性。每一个键值都会被拷贝到每一个本地和远程的下级相关的span中,因此,总体上,他会有明显的网络和CPU开销

必填参数

  • baggage key, 字符串类型
  • baggage value, 字符串类型

获取一个baggage元素

必填参数

  • baggage key, 字符串类型

返回值,相应的baggage value,或者可以标识元素值不存在的返回值(译者注:如Null)


SpanContext

相对于OpenTracing中其他的功能,SpanContext更多的是一个“概念”。也就是说,OpenTracing实现中,需要重点考虑,并提供一套自己的API。 OpenTracing的使用者仅仅需要,在创建span、向传输协议Inject(注入)和从传输协议中Extract(提取)时,使用SpanContext和references,

OpenTracing要求,SpanContext不可变的,目的是防止由于Span的结束和相互关系,造成的复杂生命周期问题。

遍历所有的baggage元素

遍历模型依赖于语言,实现方式可能不一致。在语义上,要求调用者可以通过给定的SpanContext实例,高效的遍历所有的baggage元素

NoopTracer

所有的OpenTracing API实现,必须提供某种方式的NoopTracer实现。NoopTracer可以被用作控制或者测试时,进行无害的inject注入(等等)。例如,在 OpenTracing-Java实现中,NoopTracer在他自己的模块中。

可选 API 元素

有些语言的OpenTracing实现,为了在串行处理中,传递活跃的SpanSpanContext,提供了一些工具类。例如,opentracing-go中,通过context.Context机制,可以设置和获取活跃的Span


原理和架构设计

原理和架构设计

1.自动采集&无侵入:我们使用插件化方式 JavaAegnt启动

2.跨进程传递Context:针对不同协议将信息加入到协议头里面,方便进行区分

3.TraceId的唯一性

4.性能影响:我们不能所有数据都采集这样子数据量太大了还影响效率,我们只采样必要数据

Agent和Plugin插件

Agent:我们项目启动时自动加载我们的插件进行字节码增强,我们的Agent里面由很多插件,分为自带插件和可选插件。我们要启动Agent的话就在JVM参数那指定一下就行了

Plugin插件:创建Span加入Trace调用链,数据传输时我们将数据加入到Header协议头。我们的Skywalking里面把很多的第三方调用组件封装起来了,所以够用


TraceSegment和TraceId原理

TraceSegment:

1.指的是一个进程中所有的Span的集合

2.如果多个线程协同产生同一个Trace(例如多个RPC调用不同的方法),它们只会共同创建一个TraceSegment

3.支持多入口,所以Skywalking去除了树节点RootSpan的概念,提出了三种Span模型

TraceId:

1.TraceId应该是全局唯一的

2.我们的TraceId是根据时间错+算法生成的,所以会有时间回拨问题

3.我们有个变量lastTimeStamp保存上次TraceId生成的时间,然后在生成TraceId前进行比较,如果CuurentTimeMills比lastTimeStamp时间小,说明时间回拨了,我们就不生成Id,这样来保证TraceId全局唯一

JavaAgent可以对字节码做静态修改和动态修改,我们的SkyWalklng是对字节码静态修改的


SkyWalking基本使用

图片介绍

服务和服务之间也可能存在各种调用


 

skywalking是以插件的形式实现相关东西

他能实现很多应用的无侵入式的监控

关键概念:

服务

服务实例

端点

这个就是服务,然后我们有9个服务实例

这个用户的URL请求地址我们称作端点


搭建OAP服务和UI服务
 

Downloads | Apache SkyWalking

去到download界面


 


Skywalking APM已经集成了 BoosterUI和Skywalking Website
 

下载Agents,下载我们自己需要进行代理的一个探针
 

这种探针才是用来监控我们自己的应用的,我们上面的那个是服务


 

skywalking是Java写的
 

三种启动命令


 

startup.sh
oapServic.sh
webappService.sh


 

tar -zxvf 开始解压

我们进入apache-skywalking-apm-bin的bin目录

oapService是直接启动
 

oapServiceInit是初始化启动
 

oapServiceNoInit是不初始化启动

我们启动

sh startup.sh


这样子就说明我们两个都启动成功了


 

我们还可以进入日志目录,看看我们是否有日志


 

opa.log是我们的服务端的日志
 

console.log是我们的web界面的一个日志
 

其实有4个日志,如果是两个日志就说明Java环境有问题


查看我们的日志

tail -f -n200 skywalking-oap-server.log

我们有内存型的数据库,这种数据库安全性不是太高


 

所以我们打算把日志存到我们的ES里面

我们看看我的的另一个日志skywalking-webapp
 

tail -f -n200 skywalking-webapp.log

启动失败了,因为我服务器里已经有8080的项目在用了


 

我们启动服务我们没有给它指定端口


 


 

我们看webapp目录里面其实它是一个SpringBoot项目
 

它的默认端口是8080


 

vim application.yml

然后我们把我们的端口改成18080


我们重新启动一下我们的webappService

sh webappService.sh


 

进入日志目录,重新看一下我们的日志

tail -f -n200 skywalking-webapp.log

成功了,我们的端口是18080



然后我们访问一下我们的18080端口
 

就进入了我们的skywalking界面


结构解析与设计目标

receiver Cluster

receiver Cluster是负责收集数据的

我们从每一个不同的监控服务中去获取相关信息,通过推送或者拉取去获取一些相关的数据,包括通过http,rpc等等各种不同的形式去收集
 

Aggregator集群

然后我们把数据给我们的Aggregator集群
 

它可以做我们的数据的保存
 

可以把我们的数据持久化存储到各个不同的服务器里面
 


 

Alram告警服务

还有一块就是我们的Alarm,我们的监控告警服务
 


JavaAgent监控SpringBoot应用

我们的Agent探针是为了收集我们的对应服务的数据,然后上传到我们的skywalking服务器上去

我们把文件解压成skywalking-agent目录解压到我们的IDEA的工作目录中


 


 

这个是我们的JVM参数

-javaagent:探针java所在的位置


-DSW_AGENT_NAME=skywalking-demo


-DSW_AGENT_COLLECTOR_BACKEND_SERVICES=106.55.55.56:11800


-D表示我们的JVM参数
 

SW_AGENT_NAME是我们的代理的名字
 

SW_AGENT_COLLECTOR_BACKEND_SERVICES是我们的服务上传到什么地方去
 

之前我们的服务HTTP的端口是12800,grpc的端口是11800


 

我们重新启动我们的SpringBoot项目,发现上面打印了一堆日志

这就是帮我们找到我们的skywalking插件

然后我们的服务就出来了


ES持久化存储

我们的Skywalking默认是在内存型数据库h2存储的,我们这里有数据只是因为我们的skywalking没有重启过


 

我们重启后这些数据就没有了
我们进入application.yml文件


 

我们有个storage


 

我们有个selector,下面有个es相关配置


 

你看我们默认选中的是h2


 


我们下面有h2的配置信息,有mysql的配置信息


 


因为我们只是用来持久化存储,所以我们不用关心太多的配置信息
 

我们只用关心
 

clusterNodes:我们的ES的连接地址
 

user:用户名
 

password:密码
 

看看我们是否配置了用户名和密码


我们默认是不支持mysql的,我们要把mysql的驱动包复制到这个目录下来,然后我们才能成功连接


SpringCloud全链路追踪
 

我不只希望他记录我们的微服务之间的信息

我们还想他记录更多的信息

这个服务访问了数据库,访问了redis,访问了mq等等信息我都给他体现

这里没有网关

skywalking默认我们使用这个SpringCloud的这个情况下,它是没有那种直接支持我们的网关的那种能力的
 


 

我们目录里面有已经支持的插件plugins和可选支持的插件optional-plugins
 

这个可选的插件其实没有把我们的网关的插件引进去



 

我们搜gateway版本


 

然后把jar包弄进去


 


我们的SpringCloud是依赖于webfulx,所以我们要把webfulx引入进去


 


把这两个jar包粘贴到我们的plugins里面


看看我们的Skywalking界面

我们这会有数据库,缓存,和mq的数据


日志采集GRPC导出logback日志

我们要把我们的日志弄到我们的ES里面去
 

但是我们单纯的存储这些日志的话,这些日志和我们的链路追踪是没有关系的


 


看不出我们的日志到底是属于哪条链路的
 

所以我们希望我们对我们的日志格式做一个定制化
 

我们有个链路追踪ID,我们希望他能够在这里体现出来
 


 

我们要引入依赖


 

然后我们加上我们的logback相关配置
 

我们重新启动项目,这时候变成了TID:N/A,这是因为我们还没开始链路追踪

我们不是请求发过来,我们是不会帮我们追踪的
 

利用grpc把日志信息输出到我们的oap服务

我们是info级别的我们用grpc-log来追加进去


 

或者我们可以只把警告和错误日志追踪上去
 


Webhook实现告警通知


 


通过修改alram-setting.yml文件的配置规则


 


 

告警规则



 

我们弄一下我们的alarm-settings.yml文件

我们触发报警后,我们就会自动调用我们的webhooks里面的这个请求地址



这里有告警信息


 

然后我们配置的url那个地方我们会把报警通知发过去
 

教程是写了个Controller来进行输出和接收
 

你看我们的接收类型是List<AlramMessage>


告警通知消息通知到钉钉机器人

记得我们要找对应版本的官方文档


 

看看官方文档,这个alram警告通知支持微信,钉钉,飞书通知


 


我们弄个钉钉机器人

url


 

secret密钥


 

我们把配置粘贴进来


 

这样我们告警信息就能进到钉钉了


自定义追踪-细粒追踪Service方法

我们之前追踪的是各个服务之间也就是Controller和Controller之间
 

我们想细致化到Service和Service这种具体方法之间的调用
 

引入依赖


 

这样我们就能访问skywalking中给我们暴露的API了

TraceContext方法

我们通过TraceContext的方法来往追踪上下文对象中绑定key/value


 


 

可以从从上下文获取数据


 

Trace注解
 

我们用个Trace注解来表示当前的这个方法是我们要用来追踪的


 


tag注解

我们可以通过tag注解来放我们的key和value



 

如果value是returnedObj,说明这个value是这个方法的返回对象


 

tags注解
 

里面有多tag



http://www.kler.cn/a/556345.html

相关文章:

  • ubuntu追加path环境变量
  • 使用爬虫按关键字搜索亚马逊商品:实战指南
  • selenium环境搭建
  • DeepSeek 与网络安全:AI 在网络安全领域的应用与挑战
  • 天 锐 蓝盾终端安全管理系统:办公U盘拷贝使用管控限制
  • 上下文感知 AI Agent 将赋予我们的“超能力”
  • 2后端JAVA:下载数据库数据到EXCEL表格?代码
  • [Android]使用AlarmManager设置周期性任务
  • [C++]使用纯opencv部署yolov12目标检测onnx模型
  • idea任意版本的安装
  • 第1章:LangChain4j的聊天与语言模型
  • rk3588/3576板端编译程序无法运行视频推理
  • OpenBMC:BmcWeb实例化App
  • 清影2.0(AI视频生成)技术浅析(五):音频处理技术
  • AI Agent Service Toolkit:一站式大模型智能体开发套件
  • C++与Python:两种编程语言的区别
  • 【存储中间件API】MySQL、Redis、MongoDB、ES常见api操作及性能比较
  • windows怎样查看系统信息(处理器等)
  • 2025最新Python机器视觉实战:基于OpenCV与深度学习的多功能工业视觉检测系统(附完整代码)
  • Maven 的高级调试技巧与常见问题