ebpf实战(一)-------监控udp延迟

问题背景:
为了分析udp数据通信中端到端的延迟,我们需要对整个通信链路的每个阶段进行监控,找出延迟最长的阶段.

udp接收端有2个主要路径
1.数据包到达本机后,由软中断处理程序将数据包接收并放入udp socket的接收缓冲区
在这里插入图片描述

数据接收流程
2. 应用程序调用recvmsg等api将数据从socket缓冲区读出
在这里插入图片描述

应用程序读取数据流程
2和1之间可能由于调度等造成延迟,我们写一个bcc程序对指定接收端口和延迟大于某个值的情况进行监控

bcc程序原理
我们在流程1放入udp缓冲区时(udp_unicast_rcv_skb),记录此skb的时间

然后在流程2读取udp缓冲区时(__skb_recv_udp)时取出1中记录的skb时间,并与当前时间做差值得到延迟.

#!/usr/bin/python3
# @lint-avoid-python-3-compatibility-imports
#
# udplatency    Trace long udp recvmsg delays.
#               For Linux, uses BCC, eBPF.
#
# This script traces high delays between skb being
# ready to in recv queue and them recvmsg on CPU after that.
#
# USAGE: udplatency [-d dport] [-l lat]import argparse
import ctypes as ct
from time import strftime
from bcc import BPFbpf_text = '''
# include <linux/ip.h>
# include <linux/netfilter.h>
# include <net/ip.h>
# include <uapi/linux/bpf.h>struct data_t {u64 ts;u64 lat;
};BPF_PERF_OUTPUT(events);
BPF_HASH(recv_lat, struct sk_buff*);int kprobe__udp_unicast_rcv_skb(struct pt_regs *ctx, struct sock *sk, struct sk_buff* skb)
{struct udphdr *udp_hdr = (struct udphdr *)(skb->head + skb->transport_header);u16 dst_port = bpf_ntohs(udp_hdr->dest);if (dst_port == DST_PORT) {u64 ts = bpf_ktime_get_ns();recv_lat.update(&skb, &ts);}return 0;
};int kretprobe____skb_recv_udp(struct pt_regs *ctx)
{struct sk_buff* skb = (struct sk_buff*)PT_REGS_RC(ctx);struct udphdr *udp_hdr = (struct udphdr *)(skb->head + skb->transport_header);u16 dst_port = bpf_ntohs(udp_hdr->dest);if (dst_port == DST_PORT) {struct data_t data = {};u64 *tsp = recv_lat.lookup(&skb);if (tsp != 0) {Home = bpf_ktime_get_ns() - *tsp;}recv_lat.delete(&skb);if (data.lat >= LAT_NS) {bpf_probe_read_kernel(&(data.ts), sizeof(*tsp), tsp);events.perf_submit(ctx, &data, sizeof(data));}}return 0;
}
'''class EventData(ct.Structure):_fields_ = [("ts", ct.c_ulonglong),("lat", ct.c_ulonglong)]def print_event(cpu, data, size):event = ct.cast(data, ct.POINTER(EventData)).contentsprint("%-8s ts:%d lat: %dms\n" % (strftime("%H:%M:%S"), event.ts, event.lat / 3000000))parser = argparse.ArgumentParser(description="Track udp recv latency")
parser.add_argument("-d", "--dport", type=int, required=True,help="udp dst port")
parser.add_argument("-l", "--lat", type=int,help="report latency > ns, default is 3000000")
args = parser.parse_args()lat_ns = 3000000if args.lat:lat_ns = args.latbpf_text = bpf_text.replace('DST_PORT', str(args.dport))
bpf_text = bpf_text.replace('LAT_NS', str(lat_ns))# initialize BPF
b = BPF(text=bpf_text)b["events"].open_perf_buffer(print_event)
while True:try:b.perf_buffer_poll()except KeyboardInterrupt:exit()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/214508.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Docker实用篇

Docker实用篇 0.学习目标 1.初识Docker 1.1.什么是Docker 微服务虽然具备各种各样的优势&#xff0c;但服务的拆分通用给部署带来了很大的麻烦。 分布式系统中&#xff0c;依赖的组件非常多&#xff0c;不同组件之间部署时往往会产生一些冲突。在数百上千台服务中重复部署…

Apple Vision Pro 开发机申请

申请地址: &#xff08;免费租用形式&#xff09; Developer Kit - visionOS - Apple Developer 上海Apple Lab 互动申请&#xff1a; View - Meet with Apple Experts - Apple Developer (需要完善的产品才能去测试哦) 它是如何工作的 我们将借给你一个Apple Vision Pro开发…

Go 语言中结构体的使用和示例

结构体&#xff08;简称struct&#xff09;用于创建不同数据类型的成员集合&#xff0c;放入一个单一的变量中。虽然数组用于将相同数据类型的多个值存储在单一变量中&#xff0c;但结构体用于将不同数据类型的多个值存储在单一变量中。结构体对于将数据组合在一起以创建记录非…

Linux(6):文件与文件系统的压缩,打包与备份

压缩文件的用途与技术 由于 1 byte 8 bits &#xff0c;所以每个byte当中会有8个空格&#xff0c;而每个空格可以是0,1。 其实文件里面有相当多的『空间』存在&#xff0c;并不是完全填满的&#xff0c;而『压缩』的技术就是将这些『空间』填满&#xff0c;以让整个文件占用…

5分钟搞定!学会使用pytest测试框架!

本文将会把关于 Pytest 的内容分上下两篇&#xff0c;上篇主要涉及关于 pytest 概念以及功能组件知识的介绍&#xff0c;下篇主要以一个 Web 项目来将 Pytest 运用实践中。 为什么要做单元测试 相信很多 Python 使用者都会有这么一个经历&#xff0c;为了测试某个模块或者某个…

原始类型 vs. 对象实践应用

● 首先是原始类型的例子 let lastName Williams; let oldLastName lastName; lastName Davis; console.log(lastName.oldLastName);● 然后是对象的例子 const jessica {firstName: Jessica,lastName: Williams,age: 27, }; const marriedJessica jessica; marriedJess…

教育数字化转型:塑造未来学习新范式

在国家教育数字化战略行动指引下&#xff0c;我国正积极推动数字化赋能教育高质量发展&#xff0c;以塑造教育发展的新优势。如今&#xff0c;随着科技新基建的普及和数字化赋能教育的深入推进&#xff0c;未来的教育模型正在逐渐形成。 在新的教育模型中&#xff0c;数字化学…

Doris中的物化视图(十八)

物化视图就是包含了查询结果的数据库对象&#xff0c;可能是对远程数据的本地 copy&#xff0c;也可能是一个表或多表 join 后结果的行或列的子集&#xff0c;也可能是聚合后的结果。说白了&#xff0c;就是预先存储查询结果的一种数据库对象。 在 Doris 中的物化视图&#xf…

docker的使用方法

文章目录 为什么要用dockerdocker安装docker工作原理docker命令docker搭建练习docker可视化docker镜像docker容器数据卷DockerFiledocker全流程Docker网络原理docker composedocker swarm 为什么要用docker 官网&#xff1a;https://www.docker.com文档地址&#xff1a;https:…

Jmeter接口测试——使用教程(上)

前言 jmeter是一款小巧&#xff0c;轻便、开源的性能测试工具&#xff0c;它也可以很方便的进行接口测试。 下面我就带大家学习下jmeter接口测试。 一、Jmeter简介 Jmeter是apache公司基于java开发的一款开源压力测试工具&#xff0c;体积小&#xff0c;功能全&#xff0c;使…

Java 之 final 详解

目录 一. 前言 二. final 的基础使用 2.1. 修饰类 2.2. 修饰方法 2.2.1. private 方法是隐式的 final 2.2.2. final 方法可以被重载 2.3. 修饰参数 2.4. 修饰变量 2.4.1. static final 2.4.2. blank final 2.4.3. 所有 final 修饰的字段都是编译期常量吗&#xff1f…

10年测试老鸟,自动化测试经验10条建议,一路狂飙...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、哪一刻&#x…