分布式链路追踪
2022-10-08 13:47:21 40 举报
AI智能生成
分布式链路追踪简介
作者其他创作
大纲/内容
Web 页面中的白屏时间、DOM 元素/资源加载耗时、文档网络耗时;App 的卡顿率、崩溃率、热启动加载时长
用户体验监控
在 Web 页面中,如果出现脚本错误,则需要将相应的异常信息通过日志的方式上报服务器
App 也会有相应的日志输出,但移动端更关注系统崩溃或出现异常时的日志信息
日志
访问量、成功率、响应时间等
端到端
访问是否可用、响应耗时长短等。这与 CDN、DNS 等
可用率
端上访问
响应时间、QPS 等
MySQL 中的慢查询监控
Kafka 中的 Lag 监控
执行情况
如内存级别的 Redis 会消耗大量的内存
Kakfa 则因为要进行磁盘写入所以会要求较好的 I/O
资源消耗
JVM 监控,比如 GC 时间、线程数、FGC/YGC 耗时等信息
VM监控指标
应用访问量到达阈值
容量
如是否会存在两个服务之间的相互循环引用,下游服务出现问题是否会干扰整个流程的执行
服务之间的响应时长、上下游服务的依赖程度等
服务关系
应用自身日志
三方组件日志,如MySQL 的进程日志、慢查询日志等
应用日志
当前服务是否存活、服务运行是否稳定等
ES 中可以看到服务的状态(RED、YELLOW、GREEN)
Eureka
健康情况
应用程序
如网站系统中我们会关注 PV、UV 等参数
支付系统中,我们则会关注创建订单量、成单量等
业务监控
I/O 使用率、CPU 利用率、内存使用率、磁盘使用率、网络使用率、负载等
资源利用
主机与主机之间的网络情况
通信情况
基础设施
监控数据来源
统计指标
链路追踪
可观测性核心概念
数据观测
一般会将日志设置为调试级别,或者在上线前将它们统一删除
便于调试
快速定位问题
高度定制化
信息埋点
追踪数据变化
数据分析
功能
trace
在测试或本机环境中使用
方便对程序的调试
debug
如信息埋点、追踪数据变化、数据分析等
info
用来记录一些虽然出现了错误,但是并不会真正对程序执行构成影响的内容
warning
当整个接口、方法调用都产生了不可避免的问题,对业务的主流程造成影响时才会采用的日志级别
error
fatal
日志级别
网页、App、小程序
打点的形式上传到后端服务,再记录下来
终端层
请求 IP、请求 UA,还包含与下游服务相关的 IP 地址、响应时长信息等
访问日志
错误日志
网关层
如 Java 开发人员使用最多,最熟悉的 Tomcat
容器启动日志
请求访问日志
基于容器托管的应用程序
通过框架编写
普通的应用程序
应用层
应用运行时产生的日志
慢查询日志
审计日志
组件层
记录系统中比较关键的日志
当系统启动了某个程序,或某个程序因为内存过高引发了系统级别的 kill ,就会记录在这个文件中
一般指的是 Linux 平台中的“/var/log/messages”
系统日志
通常 Linux 的日志会通过环境变量定制
查询到哪个人在哪个时间点进行了哪些操作
在系统出现异常问题时,查看是谁,因为什么操作而导致的
操作日志
基础层
日志常见来源
在高并发的情况下,存在比较严重的锁竞争关系,会导致性能不能得到有效的发挥
log4j 1.x
更加高效的写入性能
更多的功能,比如异步日志
logback
采用 Disruptor 来进行异步日志
log4j 2.x
日志实现框架
提供了动态占位符的功能
SLF4J
日志接口框架
日志框架
系统/应用启动和参数变更
关键操作节点
大型任务进度上报
异常
日志编写位置
for 循环中
日志数量
日志编写等级
日志输出级别
无用输出参数
写入性能
在生成较高级别的日志时,低级别的日志会不停叠加字符串而占用过多的内存、CPU 资源,导致性能浪费
节约性能
便于编写
便于查看
占位符
会话标识
请求标识
参数信息
发生数据的结果
可读性
关键信息隐蔽
日志开发时
减少代码位置信息的输出
文件分类
日志review
开发完成后
日志编写方式
系统之间格式保持一致
不编写多行的日志内容
不要使用日志中的常见内容来分割
日志格式
日志归档
日志管理
日志编写
产品一般可以通过业务型指标了解到产品上线之后的真实效果如何,从而优化下一步的产品决策
业务分析
通过在系统中埋点或是统计已有数据,比如最常见的 CPU 使用率、访问 QPS、响应耗时等,开发人员可以快速了解到系统的运行状态
系统运行状态
指标功能
计数器 Counter
仪表盘 Gauge
直方图(Histogram)
摘要(Summary)
指标类型
QPS
Service Level Agreement,服务等级协议
四个九 = 8760 * (1 - 99.99%) = 0.876 小时 = 0.876 * 60 = 52.6 分钟 五个九 = 8760 * (1 - 99.999%) = 0.0876 小时 = 0.0876 * 60 = 5.26 分钟
最常见的可用性指标类似于“四个九”“五个九”,四个九指的是 99.99%,五个九就是 99.999%
SLA
Application Performance Index,应用性能指数
满意(Satisfactory):用户对于这样的响应时间是十分满意的,感觉十分流畅。容忍(Tolerating):稍微慢了一点儿,但是可以接受。失望(Frustrating):实在太慢,快要放弃了。
(满意数量 + (容忍数量 / 2)) / 总数 = Apdex 值
Apdex
常见指标
崩溃率
卡顿率
卸载率
App
白屏时间
首屏时间
网页
DNS响应时间
建立连接时间
SSL握手时间
首字节时间
下载内容时间
通用指标
2xx:响应被正常处理。一般系统中会使用 JSON 来返回数据,而 JSON 可能会有不同的业务状态码,监控时可以依据具体的情况定制。3xx:请求被重定向。如果出现了大量的重定向,一般就表明该网页存在一定的问题,而且也存在降低用户使用体验的风险。4xx:无法访问,比如我们常见的 403 无权限、404 未找到。4xx 说明业务边界存在问题,可能会导致身份信息出现问题或者页面访问异常。5xx:这个在后端比较常见,如果服务器内部出现了错误,通常也会伴随着访问出现错误。
状态码
请求时间
在 HTTP 请求层面,一般可以通过总共的请求数与 5xx 请求数之间的运算获得
总共有多少个用户访问
独立用户数
请求
RPC
熔断限流降级
数据源
自定义业务指标
数据处理
因为一个 Dubbo 接口耗时较长,线程池也没有做到很好的隔离,导致当前服务的资源完全处于等待状态,没有线程可以去处理其他的业务请求,造成了线上的故障
在使用 Dubbo 的时候,你可以通过监控线程池的资源信息掌握系统运行的状态,这其中的指标有总计的线程数、活跃线程数等
活跃数、闲置数和总共的资源数
数据库
监控任务的发送量、处理量、Lag 值、处理耗时
队列
关注命中率、内存使用率、数据量等指标
缓存
监控其请求数、耗时情况等指标
在与第三方服务通信的时候,我们一定要做好熔断降级策略
组件协作资源
业务指标
GC
内存
CPU占用率
类加载
线程
VM监控
查询耗时
TPS
主从延迟数
连接数
数据量
Lag
发送数量
消费数量
分区数
响应时间
缓存命中率
网络延迟时间
已使用内存
资源链接
缓存数量
请求相关
错误数
请求处理
组件
CPU
不太建议使用 swap 区,因为它会利用磁盘的空间来代替内存,而这可能会影响到程序的使用性能
磁盘
出/入流量
网络丢包率、连接错误数
网络
文件读取/写入中的速度、耗时、次数
IO
如果程序中出现了资源流未关闭的情况,则有可能会导致句柄数激增,最终导致句柄耗尽,影响程序执行
句柄
机器信息
监控指标
获客
激活
留存
营收
传播
业务数据
关键路径
处理流程
触发行为
操作行为
线程池
自定义数据处理
处理过程
处理结果
定时/大任务处理
调用次数
调用时长/错误次数
第三方服务商对接
执行异常
性能数据
编写方向
avg
max/min
count
apdex
histogram
percentile
percent
sum
当前时间段
rate
irate
环比
同比
与之前的某个指标值的计算
指标函数
指标编写
服务之间的依赖
调用流程
开始时间
结束时间
ID
父级ID
操作名称
入口
出口
本地
操作类型
Span的构成
链路在大多数的情况下会是一个树形结构
Span之间的关系
链路图
概念
链路查询
性能分析
拓扑图
依赖关系
跨应用/语言
作用
采样率
增加埋点成本高,很难全面覆盖
占用 CPU 和内存的资源
动态增加埋点技术不可靠
代码埋点
字节码增强
链路追踪的实现方式
链路追踪的短板
在编程语言中,基本所有的代码都是运行在线程中的,并且大多数的情况下都是单线程
大多数的编程模型是基于线程的这一个概念去实现很多功能的
周期性地对执行中的线程进行快照操作,并聚合所有的快照,来获得应用线程在生命周期中的执行情况,从而估算代码的执行速度,查看出具体的原因
性能剖析介绍
不方便查看函数名称等信息
很难发现非叶子节点的问题
火焰图更擅长快速展现出问题所在,能够最快速地找到影响最大的问题的原因
火焰图
内容显示相对较长
栈帧深度较多时,容易显示不全信息
树形图则更倾向于具体展示出栈的执行流程,通过执行流程和耗时统计指标来定位问题的原因
树形图
性能剖析展现方式
性能剖析
更精准
更动态
更通用
优势
服务
实例
端点
维度
耗时
Percentile
Histogram
延迟
topN
数据
指标聚合
可视化
数据化
动态性
优点
了解整个系统的架构、服务和服务之间的依赖
操作
绘制拓扑图
通信数据
日志+异常信息
可以添加的数据内容
定制链路与数据
链路分析
黑盒监控指的是监控外部用户可见的系统行为
白盒监控指的是监控内部暴露出来的指标信息
什么是黑/白盒监控
端口状态:通过程序检测具体业务的端口是否存活
证书检测:通过检测证书是否有效,确认用户是否可以正常访问
探活:通过心跳检测来判定服务是否存活
端到端功能检测
黑盒监控
指标
白盒监控
监控数据
Google 针对大量分布式监控的经验总结,它可以在服务级别帮助衡量终端用户体验、服务中断、业务影响等层面的问题,有 4 类指标信息,分为错误、延迟、流量和饱和度
多指监控云主机、进程等机器信息,一般不代表服务的真实运行状况
基础监控
指的是监控业务系统内部的执行状态
在基础层中,我们可以把系统宕机、进程或者端口挂掉、网络丢包这样的情况认定为是故障
在业务层中,监控的内容也就相对比较多了,比如 Dubbo 调用出错、日志中出现的错误,都是可以被认定为“错误”的指标
当前系统所有发生过的错误请求
以立即看出来的错误
显示错误
表面上显示完全正确,但是在数据中已经出现异常的错误
隐式错误
在表面上显示正确,但是可能因为某种策略被认定为错误
策略导致错误
错误
在基础层中,我们可以监控 I/O 等待、网络延迟等信息
在业务层中,则可以监控接口调用的耗时、MySQL 查询的耗时等信息
在基础层中,常见的监控指标有磁盘的读写速度、网络 I/O 情况等
在业务层中则有请求量、MySQL 查询次数等等
流量
在基础层中,需要监控的指标有 CPU 使用率、I/O 使用率、句柄使用情况等
在业务层中则会有线程池的线程使用数、JVM 中的堆内存使用率等信息
饱和度
环境指标
黑白盒监控
通过监控数据,可以早于用户发现问题
通过聚合相关的指标快速定位问题
制定个性化的告警规则
制定告警规范
告警的作用
端口状态:通过观测端口的运行情况快速感知到程序是否在真实地运行
证书检测:通过检测证书快速感知证书服务是否可用
服务探活:保证业务系统或者第三方组件处在可用状态
拨测:目前互联网中都会有的一个服务质量的检测工具
端到端功能检测:通过场景、流程化的方式调用业务,检测业务是否处在可用的状态
黑盒
白盒
告警数据来源
错误类:某个组件、服务或者接口出现执行错误
延迟类:服务之间的通信耗时,或者是服务本身的耗时
流量类:服务本身所承担的访问压力
资源类:组件或者基础服务中的资源使用情况
故障分类
系统告警
简化数据
易于告警
好处
将告警数据来源聚合成为一个个指标,通过数字化、可量化的形式统一处理
告警与指标
时间点
主体
测量值
将指标数据存储在时序数据库中
指标数据存储
通过时序数据库的存储,你就可以结合一些特定的查询方式来聚合结果,从而得到我们的指标数据
时序数据库的聚合方式就是通过主体数据检索,筛选出相对应的数据集,最终利用一些指标函数的计算,得出我们的指标数值
指标数据计算
时间范围:针对某个时间段内的数据进行告警
检索范围:你要设定成告警的数据内容
判断方式:检索数据后会产生出一个当时的计算数值,根据这个值判定是否需要告警
设定规则
告警规则与设定
告警简化就是简化系统中需要告警的指标,让告警更精简
建议前期使用较为保守的阈值,尽可能地减少误报,后期再根据数据值和告警情况统计分析,对这个阈值提高或者是减少
选择阈值
保证实时性
让告警随时可以操作,比如出现了误报后随时可以取消告警、调整告警规则或是其他操作
告警操作
对于不常用的告警配置规则,运维和开发人员应该定期去进行检测其是否在生效
定期删除
如何简化告警系统
告警简化
不同的告警级别设置不同的频率
分级告警
流程跟进
告警频率
黄金指标
告警质量
warning:警告级别
problem:问题级别
critical:重要级别
告警分级
通常指出现告警或者故障时,相对比较容易处理的问题,一般和告警分级中的 warning 级别对应
事件单
如果某个事件内容持续出现,并且并没有被处理,事件单就会升级为问题单,然后进一步通知开发人员,直到开发人员的 TL。在告警规则中,problem 级别的告警会直接被认定为问题单
问题单
如果指定的问题依旧没有被处理,此类任务就会再次升级为故障单。故障单一般是系统出现了严重错误,此时影响面相对较广,需要更多的人来参与到问题的处理,及时修复问题。这和告警分级中的 critical 相互对应
故障单
故障分级
分级
某个服务出现问题时,可以依据 CMDB 中的服务负责人找到对应的开发人员
CMDB 集成
事件单:当事件单触发后,一般只会通过企业内的沟通协作软件通知,比如常见的钉钉、飞书、企业微信
问题单:此时可能需要用到短信的形式通知相关人员,对比较重要的服务可能会采用电话的形式联系相关的通知人员
故障单:告警系统会电话联系相关的负责人,并且将此服务的主要负责人和运维相关负责人主动拉入线上的群中,让大家共同解决此问题
通知方式
发生时间:告警发现时的确切时间
发生错误的现象:此次告警主要是具体哪个指标出现了错误,阈值和当前的真实值分别是多少,具体受影响的是哪个服务等等信息
错误详情:通过具体链接的形式,可以告知你如何持续跟进这个问题。一般会直接和当前相关的问题单挂钩,有时也会明确指出相关指标或者错误信息的详细链接,来进行更细一步的查看
通知内容
与内部系统结合
通过轮值的方式,某一个时间段内只交给具体的某一个人去处理线上的问题,这样负责的人可以集中自己的注意力,也不会影响到其他开发人员的工作进度
on-call 轮值制度
一般每个团队中至少有一个人负责处理一段时间内的问题,这个时间可能是一天也可能是一周,一般由团队内部决定。这个人员需要了解一定的业务,可以找到问题原因。当出现问题时能够帮忙协助定位或者寻找相关的负责人,能跟进故障并解决问题
on-call 人员
on-call 的开发或者运维人员,主要负责对生产环境中当前出现或即将出现的问题进行风险评估,并跟进问题、找出原因,最终解决问题。一般对于紧急的故障问题,要求 5 分钟内响应,非紧急的内容则是 30 分钟
on-call 处理内容
告警与人员
汇总数据
可操作性
跟进日志
可搜索
告警系统
根据重要级别确认告警内容是由于短暂的问题导致的异常信息,还是会向更严重的级别发展
当天需要给出响应的解决办法,并跟进后续的改进
在此次告警处理完成后,可以记录问题出现的原因和如何恢复的
对于此次告警,后续会有哪些改进措施来避免此类问题
非重要级别告警
事故总控负责人:负责把握此次故障的整体进度,协调人力资源来处理此次告警。在处理完成后汇总整体流程,完成最终的故障复盘、后续跟进等工作。一般来说,负责人是 on-call 值班人员、项目负责人或是运维负责人,他是整个故障中流程跟进最重要的人员。
问题处理团队:负责问题的整体处理,与总控人员在事件中都全程参与问题原因的发现和故障的解决。这个团队可能是相关业务的开发团队,也有可能是运维团队。
重要级别告警
聚集参与者
紧急恢复,保留现场
发现原因
确认解决方案并实施
事故复盘
故障处理步骤
发生时间:问题真正出现的时间点,可以通过查询相关观测数据获得。
发现时间:得知问题的时间点,无论是人员反馈还是系统报警。
结束时间:告警被处理完成的时间点,将这部分时间减去发生时间,可以得知此次故障范围总计的时长。
处理流程:由时间节点和处理内容构成,用于说明事件恢复的整体速度。在复盘时,我们可以在这里看出来哪里流程上还有优化的空间。
故障原因:用于描述此次问题发生的主要原因,可以结合告警系统中的数据内容来展示。
影响范围:本次故障会导致哪些地方的用户无法访问或是使用流程中有哪些阻碍。
后续改进措施:故障处理完成后,后续的跟进也很重要。这部分内容可以帮你了解如何避免类似的问题,如何更快地得知问题,如何降低其发生的概率,或者是如何从根本上解决。这里要列出相关的解决方案、处理人和处理事件节点。这是防止类似问题发生的关键步骤
复盘形成的故障单内容
人员处理
告警处理
日志聚合:将不同系统之间的日志组合到同一个系统中,不用再登录到每台机器上查看日志内容
统一格式:将所有收集到的日志按统一的格式汇总
我们在查看问题时,只需要找到相关的 trace 信息,就可以找到这个链路在所有层面中的日志内容
日志串联
socket:在程序中使用 socket 链接将日志内容发送到日志收集器中
agent:程序将日志内容写入本地磁盘中,在这个程序所属的机器或者容器中部署日志收集程序,当日志文件变化时,将日志变化的部分收集并发送到收集器中
日志收集
统一日志格式:统一所有业务系统中生成的日志格式,均使用同一种日志规范
自定义日志解析
日志解析
选择支持海量存储的数据库,比如 ElasticSearch 和 HDFS、ClickHouse
日志存储
日志存储到了数据库之后,我们可以通过 UI 界面检索数据
日志搜索
原理
Logstach 就充当了日志采集和日志解析工作,Elasticsearch 用于数据存储,Kibana 用于数据检索
收集到数据之后,它会将数据发送至 Kafka 集群中
接下来 Logstash 就可以启动一个集群来消费 Kafka 集群中的日志信息
也会使用 Filebeat 来代替 Logstash 完成数据采集工作
系统架构
ELK
通过查看指标数据了解指标的走向,从而更好地优化系统、流量等内容
通过导出或者查询已有数据,将一段时间内的数据以 dashboard 的形式进行展示,这个也是目前主流的一个使用场景
基于预先配置好的告警规则,定时检测数据是否符合规则,并对其进行告警处理
监控系统从服务器或者服务中获取数据,并将其统一收集到监控系统中
push,推送模式。定期主动将数据内容发送给收集器端
pull,拉取模式。业务系统主动暴露相关的数据指标信息,收集器端利用服务发现能力感知所有可能的服务列表,并定期通过发送请求的方式获取数据内容
数据采集:对于推送模式来说,业务系统一旦启动,便会定期主动将数据信息上报;拉取模式则是暴露指标,由收集器决定是否获取数据
可扩展性:推送模式可以随时扩展新的节点信息,实现线性增长;拉取模式的工作负载由业务系统的数量决定,如果业务系统数量不断增加,收集器系统也只需要动态增加机器
安全性:推送模式本身就是安全的,业务系统可以防止遭受到远程攻击;拉取模式一般采用轮训协议,可能有潜在的访问攻击
灵活性:推送模式相对不灵活,因为它只能定期发送数据;拉取模式则可以随时获取数据
系统耦合:推送模式对于系统耦合性相对较高,因为它需要获取到收集器列表,并对其进行发送数据处理,如果收集系统出现问题,数据可能会丢失;拉取模式的耦合性则相对较低
二者区分
数据收集
将数据按照主体部分,以时间维度进行按照秒或者分钟级别来聚合,然后根据不同的数据类型计算相应的数值
最后将得到的数据存储到数据库中
指标存储
指标查询
检测时间:多长时间检测一次告警内容,时间越短说明检测的周期越密集
告警规则:进行告警规则的配置,通常会包含统计指标的名称、查询方式和阈值构成
通知方式:符合告警规则后会进行相关的告警操作
规则告警
主要是采取拉取模式获取数据,同样提供了 PushGateway,让业务程序能够推送数据,再由收集系统来收集
通过 TSDB 存储引擎聚合数据,然后存储到磁盘上
提供了一套完整的查询语言 PromQL,通过 HTTP 服务的形式对外提供查询接口和基础的展示界面
Grafana 是一个强大的可视化监控指标展示工具,我们可以自定义页面中所需要展示的内容,来定制属于自己业务中的关键指标的 Dashboard
基于 Prometheus 中的配置方式来管理所有的告警内容
业务数据收集
PromQL
定期执行 PromeQL 中的语句,当符合条件时进行告警
告警规则
一个通过可视化的形式查看指标数据的展示系统
Grafana
Prometheus
指标体系
全链路记录
快速检索
快速定位
便于沟通
从业务系统或者组件中采集实时的流量数据,将这些数据汇聚成统一的格式,然后发送到链路收集服务中
链路采集
数据采集
数据查看
使用数据埋点的方式来进行观测
消息传递是在链路追踪中保持上下游服务相同链路的关键,一般会通过消息透传的方式来做到
消息传递
数据展示
Zipkin
SkyWalking 则是一个完整的 APM(Application Performance Management)系统,链路追踪只是其中的一部分
SkyWalking 中提供的组件更加偏向业务应用层面,并没有涉及过多的组件级别的观测;Zipkin 提供了更多组件级别的链路观测,但并没有提供太多的链路分析能力
系统定位
支持从 Prometheus 中拉取数据到 SkyWalking,也支持程序通过 micrometer 推送数据
Metrics System:统计系统
Agents: 业务探针
Service Mesh
是整个后端服务的接入入口,专门用来收集各个指标,链路信息
接收器集群
Receiver Cluster
汇总接收器集群收集到的所有数据,并且最终存储至数据库,并进行对应的告警通知
聚合服务器
Aggregator Cluster
链路分析实践与原理
Skywalking
观测分析
分布式链路追踪
0 条评论
回复 删除
下一页