简介

notion image

一、分布式链路追踪简介

随着业务系统的不断发展、微服务架构的演进,从原来的单体应用架构、垂直应用架构、分布式 SOA 架构到现在的微服务架构,系统逐步走向微服务化以适应用户高并发请求等需求。在微服务架构中,一个业务操作往往需要多个服务间协同操作,而在一个复杂的系统中出现问题的时候,需要我们能够快速的分析并定位到问题的原因,这就需要我们对业务进行一次还原,正是分布式链路追踪需要解决的问题。
notion image
分布式链路追踪就是将一次请求还原成完整的链路,将一次分布式请求的调用情况集中展示,例如请求耗时、请求节点的名称、响应状态等。 分布式链路跟踪主要功能: 故障快速定位:可以通过调用链结合业务日志快速定位错误信息,包括请求时间、响应的状态、节点名称等信息,用于到达故障定位的能力; 链路性能可视化:各个阶段链路耗时、服务依赖关系通过可视化界面展现出来; 链路分析:通过分析链路耗时、服务依赖关系可以得到用户的行为路径,汇总分析应用在很多业务场景。

二、分布式链路追踪的基本原理

2.1 Dapper 模型

链路追踪系统最早是由Goggle公开发布的一篇论文《Dapper, a Large-Scale Distributed Systems Tracing Infrastructure》,这篇论文讲述了 Dapper 链路追踪系统的基本原理和关键技术点,通过一个分布式全局唯一的 id(即traceId),将分布在各个服务节点上的同一次请求串联起来,还原调用关系、追踪系统问题、分析调用数据、统计系统指标。
notion image
图中一条完整的链路是:user -> 服务A -> 服务B -> 服务C -> 服务D -> 服务E -> 服务C -> 服务A -> user,服务之间经过的每一条链路构成了一条完整的链路,并且每一条局部的链路都可以用唯一的 trace id标识。
notion image
通过唯一的 trace id无法知道先是调用了服务A还是先调用了服务B,因此为了去表达这种父子关系引入了 span 的概念,相同层的 parent id 相同,span id不同,并且 span id 由小到大来表示请求的顺序。除此之外,还可以记录其他的一些信息,比如发起服务的名称、IP、被调用服务的名称、返回结果、网络耗时等。

2.2 OpenTracing 模型

OpenTracing 是一个中立的分布式追踪的 API 规范,提供了统一接口方便开发者在自己的服务中集成一种或者多种分布式追踪的实现,使得开发人员能够方便的添加或更换追踪系统的实现。OpenTracing 可以解决不同的分布式追踪系统 API 不兼容的问题,各个分布式追踪系统都来实现这套接口。 OpenTracing 的数据模型,主要有以下三个: Trace:可以理解为一个完整请求链路,也可以认为是由多个 span 组成的有向无环图(DAG); Span:span 代表系统中具有开始时间和执行时长的逻辑运行单元,只要是一个完整生命周期的程序访问都可以认为是一个 span,比如一次数据库访问,一次方法的调用,一次 MQ 消息的发送等;每个 span 包含了操作名称、起始时间、结束时间、阶段标签集合(Span Tag)、阶段日志(Span Logs)、阶段上下文(SpanContext)、引用关系(Reference); SpanContext:Trace 的全局上下文信息,span 的状态通过 SpanContext 跨越进程边界进行传递,比如包含 trace id,span id,Baggage Items(一个键值对集合)。
notion image
对于一次完整的登录请求就是一个 Trace,显然需要一个全局的 trace id 来标识,每次服务间的调用就称为一个 span,通过对应协议将 span context 进行传输。 据此调用链路信息画出调用链的可视化视图如下:
notion image

三、SkyWalking的原理

3.1 数据采集上报

notion image

3.2 跨进程传递数据

数据 data 一般分为 Header 和 Body, 例如 Http 请求的请求头和请求体, RocketMQ 也有 MessageHeader,Message Body, 请求体一般放着业务数据,所以不宜在请求体中传递链路数据,应该在 Header 中传递链路数据比较合适。
notion image
在 Dubbo 中的 attachment 就相当于 header,所以我们把 context 放在 attachment 中,这样就解决了 context 的传递问题。

3.3 无侵入的字节码增强

JVMTI 提供了一套”代理”程序机制,可以支持第三方工具程序以代理的方式连接和访问 JVM,并利用 JVMTI 提供的丰富的编程接口,完成很多跟 JVM 相关的功能。在 Instrumentation 的实现当中,存在一个 JVMTI 的代理程序,通过调用 JVMTI 当中 Java 类相关的函数来完成Java 类的动态操作。除开 Instrumentation 功能外,JVMTI 还在虚拟机内存管理,线程控制,方法和变量操作等等方面提供了大量有价值的函数。   在JVM启动时,通过JVM参数-javaagent,传入agent jar,Instrument Agent 被加载 也可以在JVM启动后,attach agent包 skywalking 的工作方式就是在 JVM 启动时,通过JVM参数 -javaagent。 Skywalking Agent 就使用 Javaagent 了做字节码植入,无侵入式的收集,并通过 Http 或grpc 方式发送数据到Skywalking Collector(链路数据收集器)。skywalking agent 为了能够让更多开发者加入开发,并且能够有可扩展性,使用了插件机制, agent 启动时会加载所有 plugins,进行字节码增强。 在插件中主要考虑问题: 创建 span,让它能够显示 Trace 调用链;考虑如何传输。

3.4 架构设计

notion image
数据收集:Tracing 依赖探针(Agent),Metrics 依赖 Prometheus 或者新版的 Open Telemetry,日志通过 ES 或者 Fluentd。 数据传输:通过 kafka、Grpc、HTTP 传输到 Skywalking Reveiver。 数据解析和分析 :OAP 系统进行数据解析和分析。 数据存储:后端接口支持多种存储实现,例如 ES。 UI模块:通过 GraphQL 进行查询,然后通过 VUE 搭建的前端进行展示。 告警:可以对接多种告警,最新版已经支持钉钉。 微服务想要使用监控追踪,只要加上对应的 agent 就可以了

四、SkyWalking监控与告警应用

4.1 监控

服务告警监控:
notion image
服务之间的依赖关系图:
notion image
trace 链路查看:
notion image
JVM 指标监控:
notion image

4.2 告警

notion image
告警配置文件alarm-settings.yml ,告警配置由以下几部分组成: service_resp_time_rule:告警规则名称 ***_rule; indicator-name:指标数据名称; op: 操作符: > , < , =; threshold:目标值:指标数据的目标数据 如 sample 中的1000就是服务响应时间,配合上操作符就是大于 1000ms 的服务响应; period: 告警检查周期:多久检查一次当前的指标数据是否符合告警规则; counts: 达到告警阈值的次数; silence-period:忽略相同告警信息的周期; message:告警信息; webhooks:服务告警通知服务地址。 也可以在该配置文件中自定义 webhook 接口,当产生告警时会调用该接口获取 AlarmMessage 信息。例如:配置钉钉告警机器人。

4.3 性能

看一下官方基于 skywalking 3.2 java 探针的压力测试,测试物理机的配置:4 Intel(R) Core(TM) i5-4460 CPU @ 3.20GH, 16G memory。
基线指标值:
CPU
: CPU 总体百分比,注:如4核 CPU 此百分比为基于400%计算而来;
TPS
: 每秒事务数;
Response
Time
. 响应时间,单位:毫秒。
notion image
每秒超过5000个 trace segment 的发送对应资源使用和响应时间来看,skywalking 探针的性能表现是非常优秀的。

五、总结

本文简单讲了分布式链路追踪的原理、Skywalking 设计和应用。总的来说,Skywalking 架构简单、利用无侵入的字节码增强技术使用很方便,扩展性强,对 Java 程序分布式监控方案提供了很大的便利性,方便我们更快速定位问题原因。
Loading...
目录
文章列表
王小扬博客
产品
Think
Git
软件开发
计算机网络
CI
DB
设计
缓存
Docker
Node
操作系统
Java
大前端
Nestjs
其他
PHP