首页 > 其他分享 >云原生中如何构建链路追踪

云原生中如何构建链路追踪

时间:2023-04-05 22:32:10浏览次数:34  
标签:原生 eBPF 探针 开发者 内核 链路 分布式 追踪

追踪面向的是请求,可以通过获取请求执行的相关数据,轻松分析出请求中的异常点,针对云原生架构下的追踪,大体可以分为针对主机的动态追踪(DynamicTracing),以及针对微服务的应用行为追踪。

动态追踪是一种高级的内核调试技术,通过探针机制,采集内核态或者用户态程序的运行信息,而不需要修改内核和应用程序的代码。这种机制性能损耗小,不会对系统运行构成任何危险。因此,它能够以非常低的成本,在短时间内获得丰富的运行信息,进而可以快速地分析、排查、发现系统运行中的问题。

要实现动态追踪,通常需要在Linux中使用相应的探测手段,甚至涉及编写并编译成内核模块,这可能会在生产系统中导致灾难性后果。经过多年的发展,尽管它们的执行已经变得更加安全了,但是编写和测试仍然很麻烦。

eBPF似乎为上述问题找到了解决的福音,eBPF通过一种软件定义的方式,提供并支持了丰富的内核探针类型,提供了强大的动态追踪能力。开发者通过编写eBPF程序,可实现相应的追踪脚本,而eBPF利用自身的实现机制,保障了在内核执行动态追踪的效率以及安全性。

eBPF正是设计和实现了一种对内核进行软件定义(SoftwareDefine Kernel)的方式。控制平面是用户空间的各种eBPF程序,实现eBPF程序在内核的加载点以及执行逻辑;数据平面则是内核各种操作的执行单元,这些加载点可以是一个系统调用,甚至是一段确定的实现代码;控制平面和数据平面通过bpf()系统调用进行通信,将用户空间的控制平面逻辑,加载到内核空间数据平面的准确位置。

eBPF程序的类型分为两个方面:追踪(Tracing)和网络(Networking)。

  • 追踪:eBPF可以通过各种类型的追踪点访问与特定程序相关的内存区域,从正在运行的进程中提取信息并执行跟踪。这样开发者就可以获取关于系统的行为及其所运行的硬件的直接信息,甚至还可以直接访问为每个特定进程分配的资源,包括文件描述符、CPU、内存等的使用情况。
  • 网络:对内核网络的操作。eBPF程序允许开发者监控并且操作计算机系统中的网络流量,这也是BPF原始设计时的核心功能点。eBPF允许对来自网络接口的数据包进行过滤,甚至可以完全拒绝这些数据包。不同类型的eBPF程序可以加载到内核网络中不同的处理阶段。

在网络数据包的处理上,eBPF通常会与Linux内核的另外一个重要功能XDP(Express Data Path)一起实现。XDP是一个安全的、可编程的、高性能的、内核集成的包处理器,它位于Linux网络数据路径中,当网卡驱动程序收到包时就会执行eBPF程序,XDP程序会在尽可能早的时间点对收到的包进行删除、修改或转发到网络堆栈等操作。XDP程序是通过bpf()系统调用控制的,使用eBPF程序实现相应的控制逻辑。

BPFTrace是eBPF的高级追踪语言。它允许开发者用简洁的领域特定语言(DSL)编写eBPF程序,并将它们保存为脚本,开发者可以执行这些脚本,而不必在内核中手动编译和加载它们。它的灵感来自其他一些著名的追踪工具,比如awk和DTrace等,一些用户甚至认为BPFTrace将会是DTrace的一个很好的替代品。

无论是DTrace、SystemTap,还是BPFTrace,其实现动态追踪都是通过探针的机制,依赖于在追踪点实现的探针,进而获取相应的追踪数据。探针是用于捕获事件数据的检测点,BPFTrace在实现内核行为追踪时使用的探针主要包括动态探针(Kprobe/Kretprobe)静态探针(Tracepoint)两种,这些探针延续了以往常见的动态追踪工具所使用的探针设计。

  1. 动态探针:Kprobe/Kretprobe

eBPF支持的内核探针功能,允许开发者在几乎所有的内核指令中以最小的开销设置动态的标记或中断。当内核运行到某个标记的时候,就会执行附加到这个探测点上的代码,然后恢复正常的流程。对内核行为的追踪探测,可以获取内核中发生任何事件的信息,比如系统中打开的文件、正在执行的二进制文件、系统中发生的TCP连接等。

内核动态探针可以分为两种:Kprobe和Kretprobe。二者的区别在于,根据探针执行周期的不同阶段,来确定插入eBPF程序的位置。Kprobe类型的探针用于跟踪内核函数调用,是一种功能强大的探针类型,让我们可以追踪成千上万的内核函数。由于它们是用来跟踪底层内核的,开发者需要熟悉内核源代码,理解这些探针的参数、返回值的意义。

  1. 静态探针:Tracepoint

Tracepoint是在内核代码中所做的一种静态标记,是开发者在内核源代码中散落的一些hook,开发者可以依托这些hook实现相应的追踪代码插入。

开发者在/sys/kernel/debug/tracing/events/目录下,可以查看当前版本的内核支持的所有Tracepoint,在每一个具体Tracepoint目录下,都会有一系列对其进行配置说明的文件,比如可以通过enable中的值设置该Tracepoint探针的开关等。

与Kprobe相比,它们的主要区别在于,Tracepoint是内核开发人员已经在内核代码中提前埋好的,这也是为什么称它们为静态探针的原因。而Kprobe更多的是跟踪内核函数的进入和返回,因此将其称为动态的探针。但是内核函数会随着内核的发展而出现或者消失,因此Kprobe对内核版本有着相对较强的依赖性。

分布式追踪是实现应用链路追踪的一种重要技术手段,同时也是实现云原生可观测性的重要组成部分,其主要用于应用程序性能管理(APM,ApplicationPerformance Management)和故障定位等。常见的分布式追踪工具包括Dapper、Zipkin、Jaeger、SkyWalking、Canopy、鹰眼、Hydra、Pinpoint等,其中常用的开源分布式追踪工具为Zipkin、Jaeger、SkyWalking和Pinpoint。这些分布式追踪工具大致可分为以下三类。

1)基于SDK的分布式追踪工具。以Jaeger为例,Jaeger提供了大量可供追踪使用的API,通过侵入微服务业务的软件系统,在系统源代码中添加追踪模块以实现分布式追踪。此类工具可以最大限度地抓取业务系统中的有效数据,提供了足够多的可参考指标;但其通用性较差,需要针对每个服务进行重新实现,部署成本较高,工作量较大。

2)基于探针的分布式追踪工具。以SkyWalking Java探针为例,在使用SkyWalking Java探针时,需将探针文件打包到容器镜像中,并在镜像启动程序中添加-javaagent agent.jar命令以实现探针的启动,并完成SkyWalking在微服务业务上的部署。SkyWalking的Java探针实现原理为字节码注入,将需要注入的类文件转换成byte数组,通过设置好的拦截器注入到正在运行的程序中。这种探针通过控制JVM中类加载器的行为,侵入运行时环境以实现分布式追踪。此类工具无须修改业务系统的源代码,相对SDK有更好的通用性,但其可获取的有效数据相对SDK类工具较少。

3)基于代理实现。Sidecar作为服务代理,为其所管理的容器实现服务发现、流量管理、负载均衡和路由等功能。在流量管理过程中,Sidecar可以抓取进出容器的网络请求与响应数据,这些数据可以记录该服务所完成的一次单个操作,可与追踪中的跨度信息对应,因此可将Sidecar视为一种基于数据收集的分布式追踪工具。Sidecar无须修改业务系统代码,也不会引入额外的系统的开销。但由于Sidecar所抓取的跨度不包含追踪链路上下文,要将Sidecar所抓取的跨度数据串联成追踪链路是很困难的。

若要对一个微服务业务系统进行分布式追踪,会产生两个基本问题。第一,业务系统运行时可能会产生很多脏数据或发生数据丢失,需要在这种环境下准确地生成追踪数据。第二,面对成百上千的服务所生成的追踪数据,需要设计合适的收集与存储方案。追踪链路是以跨度为根节点的树形数据结构,在微服务中,从客户端发起一次API调用,往往后面会产生多次服务间的API调用,因此追踪链路代表一次完整操作,其中包含了很多子操作。

虽然分布式追踪技术在应用方面已经取得了一些进展,但其仍然存在着一定的局限性。当前的分布式追踪工具或者需要侵入微服务软件系统的源代码,或者需要侵入业务系统的镜像与运行环境,或者在生成的跨度信息与追踪链路的准确性与完整性上仍有缺失。

标签:原生,eBPF,探针,开发者,内核,链路,分布式,追踪
From: https://blog.51cto.com/key3feng/6171822

相关文章

  • 浅谈云原生可观测性
    随着云原生、微服务等新架构、新生态的引入和发展,可观测性(Observability)越来越多地被提及和重视。1.为什么云原生一定需要可观测性架构复杂在云原生时代,容器化的基础设施使应用自身变得更快、更轻,一台主机上可以快速部署和运行几十个甚至上百个容器[1],而Kubernetes等容器编排平台......
  • Android 原生 SQLite 数据库的一次封装实践
    作者:LiBingyan本文主要讲述原生SQLite数据库的一次ORM封装实践,给使用原生数据库操作的业务场景(如:本身是一个SDK)带来一些启示和参考意义,以及跟随框架的实现思路对数据库操作、APT、泛型等概念更深一层的理解。实现思路:通过动态代理获取请求接口参数进行SQL拼凑,并以接口返回值(泛型)......
  • 免费广告效果监测服务,实现全链路营销效果跟踪
    广告主们都希望以低预算获得更高的广告投放收益,在投放广告后,想要了解高回报的渠道,往往需要收集并分析繁杂的数据,耗时耗力。通过广告监测,广告主可以准确的追溯用户渠道来源,看到不同流量的用户价值,分析广告投放效果,从而指导广告的出价和投放素材的优化,把预算花在刀刃上。针对广告主......
  • 使用 Solon Cloud 的 Jaeger 做请求链路跟踪
    <dependency><groupId>org.noear</groupId><artifactId>jaeger-solon-cloud-plugin</artifactId></dependency>1、描述分布式扩展插件。基于jaeger适配的soloncloud插件。基于opentracing开放接口提供链路跟踪支持。2、配置示例solon.app:name:"......
  • 云原生的崛起
    2013年春,Docker技术开源宣告了云原生计算的序幕。Docker公司创新地提出了应用打包规范Docker镜像,它将应用及其所有依赖项打包,从而使应用可以在不同的计算环境之间快速、可靠地运行。容器技术提供了一个优雅的抽象,让开发所需要的灵活性、开放性和运维所关注的标准化、自动化达......
  • 【微信小程序-原生开发】实用教程14 - 列表的分页加载,触底加载更多(含无更多数据的提醒
    此页可在动态列表的基础上完善,也可以单独学习【微信小程序-原生开发】实用教程10-动态列表的新增、修改、删除效果预览核心技术列表的分页加载skip跳跃到指定下标开始查询limit限制返回的数据数量(云数据库最多20条/次,云函数最多100条/次)skip配合limit使用,便能实现分页啦!.ski......
  • 【微信小程序-原生开发】实用教程17 - 详情页触发列表页刷新,点击图片放大预览,转发给好
    详情页触发列表页刷新需求描述:在详情页进行点赞/收藏操作,再返回到列表页,发现列表页并没有同步更新点赞/收藏的状态。解决方案:在详情页执行任何触发列表页展示内容的数据更新时,都同步执行列表页的刷新代码实现:因列表页通常为详情页的上一页,所以详情页触发列表页的刷新实际上是触发上......
  • 【微信小程序-原生开发】富文本编辑器 editor 的使用教程
    表单内容较多时,通常需要输入换行的数据,此处便需要用到富文本编辑器富文本编辑器的渲染<editorclass="editorStyle"style="height:auto"id="editor"placeholder="请输入内容"bindready="onEditorReady"bindinput="contentChange"></editor&......
  • 【微信小程序-原生开发】TDesign 实战模板——带性别图标的头像
    <viewclass="avatarBoxcenter"><t-avatarbindtap="previewImage"data-url="{{detail.avatarUrl}}"wx:if="{{detail.avatarUrl}}"image="{{detail.avatarUrl}}"/><t-avatarwx:elseic......
  • 使用篇丨链路追踪(Tracing)其实很简单:请求轨迹回溯与多维链路筛选
    作者:涯海在日常生活中,我们可能都经历过以下场景:去医院看病就诊,但预约页面迟迟无法打开;新款手机发布日促销秒杀,下单页面一直卡住转菊花;游戏大版本更新,在线人数过多,导致人物一直在“漂移”。这些问题令产品体验变得非常差,有耐心的同学还会吐槽几句,没耐心的同学早已转身离开。试想一下......