Tracing 可以追踪一次用户的请求,从而大致定位问题节点。如果运气好,是可以直接呈现某段代码的问题,比如问题就是 SQL 语句慢,或者执行了非常多次的 redis 操作导致整个请求慢,但是仍然有很多的时候只呈现了 Controller 方法执行时间长。
如果请求出现错误,在整个 Logging 体系中搜索错误日志是很快能够定位出错误的原因的,但是如果是请求发生了慢的现象,就得结合 Tracing 。Tracing 基本定位到某个 Controller 的问题,日志提供进一步的问题,排查到底是为什么慢,能否排查出问题取决于日志记录完备情况,所以经常出现的情况是补充日志进一步排查问题。
通过 Metrics 中的 SRE 黄金指标能够很快确定业务是否正常,是否需要人为干预。但是一旦到某个业务慢,通过 tracing 和日志也没有发现直接线索,这个时候就只能通过 Metrics 找到有问题节点资源饱和度指标,看各种指标异常,不断地猜测试错验证了。
根据前文提到 Tracing 、Logging 、Metrics 工具在不同场景下使用,在不同工具之间跳转很麻烦会导致排查故障效率不高,但这是个工程问题,很多开源项目都在致力于解决这个问题。比如 OpenTelemetry 社区就致力于解决这个问题,会将三者从不同的线头糅合成一个线头,包括很多商业工具也都在界面跳转等易用性上发力,这个问题终将能够解决。
盲区从理论上分析就存在的,不管是何种可观测性工具都没有办法完全还原程序的执行过程。Tracing 理论上就不可能针对每行代码执行都做插桩,因为会导致程序的执行性能下降很快。 Skywalking 有 trace-profiling 技术,目标就是动态探测某个程序在干什么,这个有一定的价值,能够发现用户代码层面的盲区。
国内使用很广泛的 Arthas 也是起着类似的作用,就是发现用户代码层面的盲区。国外一些在线 debug 工具,lightingRun 等工具也是往这个目标努力。
程序执行过程是用户代码调用公共库、公共库调用 JVM 虚拟机代码、然后触发 glibc 库,最终触发 syscall 。
现有工具理论上也只是工作在用户代码和公开库之上来帮助用户理解程序执行过程。
用户在代码层执行一次带域名的 http 请求,实际在 glibc 中会分成两次网络请求,一次是获得 dns 解析,一次是真实的网络请求。用户代码层面无法理解到底是如何执行的。
程序执行过程中,由于 CPU 时间片使用完,无法获得 CPU 执行,用户代码层面会将等待 CPU 时间片执行时间算成代码执行时间
隐藏锁的使用,前文介绍了用户代码不可能对每行代码都做插桩,这样就会导致某些代码执行过程中可能在调用过程中使用了锁,但是对于用户而言是完全无意识的。典型就是 Java 常用的池化技术,连接池、线程池都是用锁来确保逻辑的正确执行。
背锅的网络质量,用户代码调用网络发送代码,网络数据真的发送出去了吗?程序这个时候如果执行了 GC 操作或者 CPU 时间片用完了呢?从用户代码和日志层面看出应该是发出网络数据了,但是中间可能存在各种原因导致网络数据发送是滞后的,开发人员会倾向于认为网络质量有问题,但是网络运维人员发现不了网络质量问题。
学习过操作系统的同学稍微回忆下基础知识,从操作系统层面看程序的执行过程,才是程序的真实执行过程,这里面是没有任何遗漏的。重点回忆下图。 程序代码是以线程为载体进行执行,线程执行过程中可能会因为 disk 、sleep 、lock 、idle 等各种原因放弃 CPU 上执行转入等待状态。 等待事件完成之后,线程状态变成 Runnale 等待 cpu 调度,如果此时 CPU 资源紧张,就会出现很长的等待时间。 开源项目 Kindling 的 trace-profiling 就是利用 eBPF 获取各个点位信息,同时结合 Trace ,真实地还原出程序的执行过程。从 Kindling 的 trace-profiling 去看 trace 的完整执行过程,每一个毫秒都知道程序在干什么。
Kindling-OriginX 商业产品(永久免费)相比于 Kindling 开源探针而言,使用 Rust 语言完全重构了 eBPF 探针。主要目的是获得更好的性能和稳定性。Kindling 开源探针使用 go 语言,由于 go gc 的存在,导致内存资源消耗相对而言比较大,而且 go gc 的时间不可控。 Kindling-OriginX 商业产品定位为故障推理引擎,通过分析各种开源工具的数据,补充 trace-profiling 的指标,比如通过 trace-profiling 已经能够看出网络执行慢了,这个时候通过补充网络质量指标如 RTT 、重传等进一步确认网络到底为什么慢。
Kindling-OriginX 的故障报告中,完成了相关指标,日志和 tracing 的完美集成,只呈现用户需要看的故障传播链路分支和指标,旁路无关分支和故障不相干指标也不会呈现,日志也是故障时刻前后的相关节点日志。同时利用 eBPF 结合 trace-profiling 技术打开程序执行和系统调用盲区,从根本上彻底还原程序执行过程,故障推理引擎利用智能算法结合 trace-profiling 自动化推导出故障根因。