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