基于eBPF的持续性能剖析方法、装置、电子设备和存储介质与流程

文档序号:36420689发布日期:2023-12-20 09:46阅读:47来源:国知局
基于的制作方法

本发明涉及云计算,特别涉及一种基于ebpf的持续性能剖析方法、装置、电子设备和存储介质。


背景技术:

1、随着企业的应用系统架构由单体架构向分布式微服务架构演进,以及研发、运维团队对高可用架构的投入,当故障发生时,可以实施各种高可用保障措施进行止损和恢复业务,比如扩容、熔断、降级、限流或者灾备切流等。而实施这些措施的依据是故障定位,故障定位的目标就是找到故障根源,使故障恢复动作更加有效。

2、但故障定位面临许多困难,尤其是云计算技术的发展使得应用的运行环境越来越复杂,需要非常全面的技术知识和丰富的经验才能胜任。而且定位所需时间因个人的能力而异,这就导致定位时长不可预期。在it运维界,高可用稳定性能力建设的目标是1-5-10,如图1所示,也就是1分钟发现,5分钟定位/处置,10 分钟恢复。

3、现有技术中的故障定位采用以下三种方法,但均存在着一定的局限。

4、1)监控系统

5、传统的故障定位主要依赖监控系统。监控系统一般是对指标和日志进行监控,当指标异常或者日志异常时进行告警。运维人员分析故障的时候,根据各种指标(包括服务的指标,系统的指标等)和日志(包括应用的日志、系统的日志等),结合历史故障处理经验以及自己掌握的知识进行溯因推理,找到故障原因。

6、所谓溯因推理,是指根据观察到的事实和数据来推断可能的原因。对应到it领域,如果业务出现延迟增加的现象,it专家会检查系统的cpu、内存、网络和磁盘等资源的指标,当技术人员看到cpu 很空,但是磁盘的利用率(utilization)指标很高,内存交换(swap)很频繁,技术人员可能会推断磁盘太忙导致了服务的阻塞,然后进一步查看发现内存非常紧张,并且内存交换空间也被大量使用,那么技术人员基本判断是因为物理内存不够,导致数据反复从内存写到磁盘,又从磁盘读进内存,从而导致服务卡顿。

7、当系统架构和环境比较简单、并且变化不大的时候,采用监控系统这种手段还是比较有效的。随着微服务、云原生架构的流行,应用系统正变得越来越复杂,一个业务功能可能由几十上百个服务组成,依赖关系盘根错节,这些服务又由大量的主机/容器承载,与数据库、中间件及网络组件相关,涉及庞大的基础设施。当终端用户的业务请求出现超时或者失败等异常时,传统的监控系统对故障定位的帮助不大,这个时候apm系统应运而生。

8、2) apm系统

9、apm全称是application performance monitor(应用性能监控)。目前大部分的apm系统都是基于dapper原理实现分布式链路追踪系统。如图2所示,为一次请求调用示例:

10、a)服务集群中包括:前端a,两个中间层b和c,以及两个后端d和e;

11、b)当用户发起一个请求时,首先到达前端a服务,然后a分别对b服务和c服务进行rpc(remote procedure call,远程过程调用);

12、c)b服务处理完给a做出响应,但是c服务还需要和后端的d服务和e服务交互之后再返还给a服务,最后由a服务来响应用户的请求。

13、dapper设计了下面的几个概念用来记录请求链路:

14、a)链路(trace):表示一次完整的调用链路。

15、b)跨度(span):表示一次完整的调用链路中的某个基本工作单元,每一次链路调用都会创建一个跨度。一次方法调用,一个程序块的调用,或者一次rpc/数据库访问,只要是一个具有完整时间周期的程序访问,都可以被认为是一个跨度。

16、链路形成包含多个跨度的树状结构,具有唯一的traceid。一次请求的每个链路,通过跨度的id(spanid)和其父id(parentid)就能串联起来,形成一颗调用树。

17、一次完整的调用链路中的每个跨度拥有相同的唯一表示traceid。跨度的结构如下:

18、type span struct {

19、traceid int64 // 用于标识一次完整的请求id

20、name string // 单元名称

21、id int64 // 当前这次调用spanid

22、parentid int64 // 上层服务的spanid,最上层服务parentid为null,代表根服务

23、annotation []annotation // 注释,用于记录调用中的详细信息,例如时间

24、}

25、apm系统可以快速发现耗时长的链路和跨度,但是不能准确解释为什么耗时长。

26、3)可观测系统

27、it界在传统apm的基础上,提出了可观测的理念和方法。总结来说,可观测体系主要由三大支柱构成,分别是logging(日志)、metrics(指标)和tracing(链路或者应用跟踪)。

28、日志logging:自动埋点/手动埋点,展现的是应用运行而产生的事件或者程序在执行的过程中间产生的一些日志,可以详细解释系统的运行状态,但是存储和查询需要消耗大量的资源。

29、指标metrics:服务、端点和实例的各项指标,是一种统计数据,存储空间很小,可以观察系统的状态和趋势,但是对于问题定位缺乏细节展示。指标的例子如:cpu使用率、系统内存占用、接口响应时间、接口qps(queries-per-second,每秒查询率)、jvm gc(javavirtual machine garbage collection,java虚拟机垃圾收集)次数和订单量等。它们用来做监控大屏是非常合适的,但是通常不能帮助排查问题。

30、链路tracing:同一traceid的调用序列,面向的是请求,可以轻松分析出某次请求经过了哪些链路,比如进入a应用后,调用了哪些方法,之后可能又请求了b应用,在b应用里面又调用了哪些方法,以及整个链路在哪个地方出错等这些问题。

31、三者之间的关系如图3所示。指标、日志、链路在监控中是相辅相成的。通过指标和日志维度,技术人员可以做一些事件的聚合统计,例如,绘制流量趋势图,某应用每分钟的错误日志数。通过链路和日志系统,技术人员可以得到某个请求的详细的信息,例如请求的入参、出参和链路中方法打印出的日志信息。通过指标和链路系统,技术人员可以查到请求调用信息,例如 sql执行总时长、各依赖服务调用总次数。

32、这三者打通最大的价值是能做到全链路错误寻根,即从发现请求的指标异常,通过指标关联分析,逐层下钻到明细链路和具体的日志,全流程自动化从宏观到明细的错误发现和根因定位。可能的排障过程是这样的:

33、a)收到一条告警,指出某个服务器的 cpu 使用率为 90%。

34、b)工程师去供应商的平台上查看指标,指标将通过带有示例的 opentelemetrysdk(software development kit ,软件开发工具包) 发送,opentelemetry是一个常用的可观测解决方案,其中的示例是时间序列中的突出显示值,包含一组键值对(key-valuepair),这些键值对将存储相关信息,包括在此期间处于活动状态的traceid。

35、c)单击 traceid 可以让技术人员立即查看该链路,或识别可能存在问题的链路之后再进行更深入的调查。这个系统甚至可以让技术人员按执行时间对这些traceid进行排序,在链路的视图中,技术人员将能够看到与该链路关联的日志,因此技术人员可以看到在给定时间内的相关内容。

36、d)由于 opentelemtry 的规范能够让日志存储traceid,所以技术人员能够确切地知道每个日志的 traceid,同时,技术人员也可以按 traceid 查找日志。

37、然而,可观测性平台是一个很大很复杂的平台,最理想的情况是能有一个后端引擎同时存储所有的指标、日志和链路数据,并进行统一的分析、关联和可视化。但是目前还没有厂商或开源产品能够较好实现这种统一,数据的统一展示与关联分析依然是一个很大的挑战。大部分公司都是用一些开源手段来堆叠,虽然能解决一些问题,但是它们各自是相互独立的,没办法很友好的进行关联,这导致在排查问题的时候需要各个平台来回切换。

38、同时,在使用可观测系统定位问题时,仍然面临很多挑战。比如异常指标太多,包括业务指标、服务/应用指标、机器/系统指标或者网络指标可能会同时发生异常,到底应该从哪个或者哪些指标入手进行排查。明确故障根因时往往还需要更细粒度的观测、更深层次的数据支撑,才能解释故障现象。

39、it系统中,每一个业务请求都是由一个线程来完成的,而从线程的视角来看,线程要么是在cpu上运行(即on-cpu),要么是在某个队列里排队等待资源(即off-cpu),比如等内存、等io、等网络、等锁、等事件(event)或者等cpu。显然,一个业务请求的总耗时等于线程on-cpu的耗时加上off-cpu的耗时。当由于某种原因导致某个等待耗时增加就使得业务请求响应时间增加,当等待耗时增加到某个极限时就会使得服务失败,造成故障。现有技术中最根本的缺陷是,所有的数据、信息都没能细粒度到线程级别,从推理的角度来说,证据链是不完整的。

40、当前服务器操作系统一般采用linux。linux 在过去十多年的发展中, 演化了很多追踪技术, 包括kprobe/kretprobes、tracepoint、systemtap、uprobe、ftrace和perf(linux 性能子系统)等。其中kprobe/kretprobes、tracepoint和uprobe属于探针的范畴,是一切的根基,而systemtap、ftrace和perf则属于框架的范畴。基于这些技术,无论是直接编写内核模块使用kprobe,还是编写systemtap脚本然后由工具生成内核模块,安全性、灵活性或者性能等方面都不太理想。

41、ebpf(extended berkeley packet filter,扩展型伯克利封包过滤器)的出现改变了这一切,它可以安全地扩展内核的功能,而无需更改内核源代码或加载内核模块。ebpf支持各种数据源,包括kprobe、uprobe、tracepoint、perf event(性能事件)等。

42、ebpf的出现突破了apm或者可观测系统的局限,ebpf起源于linux内核,它运行在操作系统内核的特权上下文,高效、安全、易于扩展而不需要修改内核源码或者加载内核模块。操作系统一直是实现观测,安全和网络功能的最理想的地方,因为内核的特权可以查看和控制整个系统。通过允许在操作系统中运行沙盒程序,应用程序开发人员可以运行ebpf程序,在运行时为操作系统添加额外的功能。基于linux操作系统能够保证安全性和执行效率,这导致了一波基于ebpf的项目,涵盖了广泛的用例,包括下一代网络、可观察性和安全功能。如今,ebpf可以被广泛用于驱动各种各样的用例:在现代数据中心和云原生环境中提供高性能的网络和负载平衡,以低开销提取细粒度的安全可观测性数据,帮助应用程序开发人员跟踪应用程序,为性能故障排除提供见解等。


技术实现思路

1、为了使得故障定位时长可控,本发明提出了一种基于ebpf的持续性能剖析方法,在可观测性三大支柱(链路、指标、日志)的基础上,基于linux内核的ebpf机制,实现系统的持续剖析(continuous profiling),具备线程级的on-cpu和off-cpu 剖析能力,达到对于故障“发生即发现,一切可回溯”的效果。本发明实施例能够持续地记录每一个线程的轨迹,可以在发生故障时,完整还原程序执行过程,分析它分别在 cpu、存储和网络等资源上消耗了多少时间,进一步地了解这段时间之内到底发生了什么,就可以辅助故障定位。

2、本发明的第一目的在于提供一种基于ebpf的持续性能剖析方法,包括以下步骤:

3、s1、通过ebpf代理和java代理实施探针埋点,用于收集线程信息;

4、s2、在微服务的节点上建立用于保存线程运行信息的数据结构;

5、s3、系统调用和进程调度的探针触发时,记录时间戳,计算事件时长,保存超过预设时长事件的数据;

6、s4、利用linux的性能事件子系统,对cpu时钟事件进行采样,获得线程的调用栈信息;

7、s5、微服务各节点上的ebpf代理和java代理把收集的线程信息发送至后端,存储于数据库中;

8、s6、利用后端数据库,在前端进行数据展示,通过性能剖析实现故障定位。

9、进一步的,所述通过ebpf代理和java代理实施探针埋点,包括:

10、s11、通过ebpf代理,在linux内核的系统调用位置实施探针埋点,用于分析系统调用事件;

11、s12、通过ebpf代理,在linux内核的与线程调度相关的函数中实施探针埋点,用于收集线程调度信息;

12、s13、通过ebpf代理,在linux性能事件处实施探针埋点,对线程进行采样,获取线程执行函数信息;

13、s14、通过java代理实施探针埋点,用于获取各种线程id和链路id的对应关系。

14、进一步的,所述在微服务的节点上建立用于保存线程运行信息的数据结构,包括如下步骤:

15、s21、在微服务的节点上建立用于保存线程异常事件的数据结构;

16、s22、在微服务的节点上建立以线程id为键的数据结构,用于节点内临时存放数据;

17、s23、在微服务的节点上建立用于保存时钟事件的数据结构。

18、进一步的,所述利用linux的性能事件子系统,对cpu时钟事件进行采样,获得线程的调用栈信息,包括:

19、s41、cpu时钟事件发生时,探针被触发,获取线程的调用栈;

20、s42、用线程id、内核态的调用栈和内核态的调用栈组成键,用于更新存储cpu时钟事件计数的数据结构;

21、s43、更新存储cpu时钟事件计数的数据结构,保存调用栈和运行时长信息。

22、进一步的,所述节点把收集的线程信息发送至后端存储,包括:

23、s51、ebpf代理把收集的线程数据发送至后端;

24、s52、java代理获取线程的id与链路id的对应关系,发送至后端;

25、s53、后端进行数据处理和存储,并生成分析图。

26、进一步的,所述利用后端数据库,在前端进行展示,通过性能剖析实现故障定位,包括:

27、s61、在前端通过图形用户界面展示收集到的数据;

28、s62、发现故障,结合故障时间点,通过链路-跨度-线程层层深入,检查跨度信息中可能存在的异常线程事件;

29、s63、根据异常线程事件的类型,检查对应指标或者可视化图形,定位故障根源。

30、进一步的,所述系统调用和进程调度的探针触发时,记录时间戳,计算事件时长,保存超过预设时长事件的数据,包括:

31、s31、线程唤醒后在cpu上运行,记录on-cpu时间戳,用于后续计算on-cpu时长;

32、s32、系统调用时,记录进入系统调用时间戳,用于后续计算系统调用时长;

33、s33、线程等待资源,记录off-cpu时间戳,减去on-cpu时间戳,计算on-cpu的时长,保存超预设时长的事件信息;

34、s34、线程获得资源,被唤醒后,进入运行队列,记录时间戳,用于计算调度延迟;

35、s35、线程on-cpu时,记录时间戳,减去off-cpu的时间戳,计算off-cpu的时长,保存超过预设时长的事件信息;

36、s36、记录系统调用完成时间,减去进入系统调用时间戳,计算整个系统调用花费时间。

37、本发明第二目的在于提供基于ebpf的持续性能剖析装置,它包括:

38、埋点模块,通过ebpf代理和java代理实施探针埋点,用于收集线程信息;

39、数据结构模块,在微服务的节点上建立数据结构,用于保存线程的运行信息;

40、线程记录模块,节点记录线程调度和系统调用的时间戳,保存超过预设时长事件的数据;

41、时钟事件采样模块,利用linux的性能事件子系统,对cpu时钟事件进行采样,获得线程的调用栈信息;

42、数据传输存储模块,节点把收集的线程信息发送至后端存储;

43、数据展示和故障定位模块,利用后端数据库,在前端进行数据展示,通过性能剖析实现故障定位。

44、本发明第三目的在于提供一种电子设备,包括:

45、存储器,用于存储计算机程序;

46、处理器,用于执行存储器上所存储的程序,实现上述任一项所述的基于ebpf的持续性能剖析方法的步骤。

47、本发明第四目的在于提供一种计算机可读存储介质,所述计算机可读存储介质内存储有计算机程序,所述计算机程序被处理器执行时实现上述任一项所述的基于ebpf的持续性能剖析方法的步骤。

48、本发明的有益技术效果:

49、1)通过在系统调用和线程调度时埋上探针,可以收集进线程粒度的信息,将获得的这些信息与现有的观测系统结合,获得线程级别的运行数据,为故障定位提供了更精准、更细粒度的数据,为运维人员提供高效的故障定位方法。

50、2)通过将进程/线程的数据与链路/跨度(trace/span)进行关联,在现有apm和观测系统的基础上,实现持续剖析,可快速地进行故障定位,实现故障的“发生即发现,一切可回溯”的效果。

51、3)基于ebpf技术,精简堆栈采样逻辑,实现保持采样精度的同时,对被观测应用性能影响很小,系统开销很低。当cpu采样频率为10mhz时,系统开销一般在1%左右。

52、4)具有线程回放功能。能够将所有线程执行的情况进行记录并重放,可以将执行的某个链路的线程标记为高亮,帮助用户理解请求时每一毫秒的具体执行内容,以便确认故障根因。

53、5)能够将链路有针对性地关联指标。通常来说,链路与日志能够很好的进行关联,因其均为代码维度。而链路与指标难以关联,因为指标是资源维度,代表程序执行过程中的资源消耗,而且指标的数据量非常庞大,排查时太消耗时间。本发明通过ebpf分析线程执行过程中资源消耗的环节,然后关联每个环节在该时间段内的相关资源指标,可以快速找到引起故障的关键指标,减少无关指标的干扰。

54、本发明的基于ebpf的持续性能剖析方法,系统开销小,数据粒度细,数据链完整,使故障的分析和定位更加迅速和精确。

当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1