通过 DeepFlow 查询函数在 CPU 上消耗的时间(CPU 性能剖析)

张开发
2026/4/13 20:25:26 15 分钟阅读

分享文章

通过 DeepFlow 查询函数在 CPU 上消耗的时间(CPU 性能剖析)
CPU 剖析的配置与应用前置条件需要内核版本支持 eBPF 能力DeepFlow 中开启 eBPF 能力默认开启所需内核版本要求如下体系架构发行版内核版本kprobe [1]Golang uprobeOpenSSL uprobeperfX86CentOS 7.93.10.0-940[2]YY[3]Y[3]YRedHat 7.63.10.0-940[2]YY[3]Y[3]Y*4.14[4]YY[3]-Y*4.15YY[3]-Y*4.16YY-Y*4.17YYYYSUSE 12 SP54.12 [5]YY-YARMCentOS 84.18YYYYEulerOS5.10YYYY麒麟 KylinOS V10 SP14.19.90-23 [6]YYYY麒麟 KylinOS V10 SP24.19.90-25.24 [7]YYYY麒麟 KylinOS V10 SP34.19.90-52.24YYYY其他发行版5.8YYYY对内核版本的补充说明[1]在 Linux 启用了 BTFBPF Type Format的情况下X86 架构内核版本大于等于 5.5、ARM 架构内核版本大于等于 6.0 时agent 将自动使用 fentry/fexit 替代 kprobe/kretprobe可获得约 15% 的性能提升。[2]CentOS 7.9、RedHat 7.6 向 3.10 内核中移植了一部分 eBPF 能力。在这两个发行版中DeepFlow 支持的详细内核版本如下依赖的 Hook 点3.10.0-957.el7.x86_643.10.0-1062.el7.x86_643.10.0-1127.el7.x86_643.10.0-1160.el7.x86_64注意 RedHat 的声明The eBPF in Red Hat Enterprise Linux 7.6 is provided as Tech Preview and thus doesnt come with full support and is not suitable for deployment in production. It is provided with the primary goal to gain wider exposure, and potentially move to full support in the future. eBPF in Red Hat Enterprise Linux 7.6 is enabled only for tracing purposes, which allows attaching eBPF programs to probes, tracepoints and perf events.[3]容器内的 Golang/OpenSSL 进程不支持。[4]在内核 4.14 中一个 tracepoint 不能被多个 eBPF program attach例如不能同时运行两个或多个 deepflow-agent。其他版本不存在该问题。[5]目前支持 SUSE 12 SP5 4.12.14但 Linux 社区的 4.12 版本依然不支持。[6]KylinOS V10 SP1 部分内核例如 4.19.90-23.48.v2101.ky10.aarch64可正常运行但不确保 KylinOS V10 SP1 所有 aarch64 架构内核都能正常运行 deepflow-agent。[7]KylinOS V10 SP2 某些内核如 4.19.90-24.4.v2101.ky10.aarch64由于不支持bpf_probe_read_user()无法读取用户态数据因此不支持 AutoTracing但支持持续剖析和文件读写追踪功能。支持语言类型支持语言/库社区版企业版on-cpuJava✔✔C/C✔✔Rust✔✔Golang✔✔Python***✔✔CUDA✔✔Lua*✔✔off-cpuJava✔C/C✔Rust✔Golang✔Python***✔CUDA✔Lua*✔on-gpuCUDA*✔mem-allocJava**✔Rust✔Golang*✔Python****✔mem-inuseRust✔hbm-allocCUDA*✔hbm-inuseCUDA*✔rdmaC/C*✔说明*开发中的功能尚未正式发布**运行 Java 程序的 JVM 必须包含符号表参考下文的 JVM 符号表检查***当前支持版本为 Python 3.10语言分类编译为 ELF 格式可执行文件的语言Golang、Rust、C/C使用 JVM 虚拟机的语言Java解释型语言Python获取 Profiling 数据需满足两个前提条件应用进程需要开启 Frame Pointer或启用 Agent 的 DWARF 栈回溯能力应用进程开启 Frame Pointer帧指针寄存器编译 C/Cgcc -fno-omit-frame-pointer编译 RustRUSTFLAGS-C force-frame-pointersyes编译 Golang默认开启无需额外编译参数运行 Java-XX:PreserveFramePointer开启该参数会禁用某些编译器优化不过根据 Netflix 和 Brendan Gregg 的实测结果通常只会引入 1% 的性能损耗。Netflix 早在 2015 年起已在生产环境大规模使用以支撑其 Java 程序的日常性能分析。启用 Agent 的 DWARF 栈回溯能力请参考文档对于编译型语言的应用进程编译时需要注意保留符号表JVM 符号表检查# 1) 查找需要进行内存剖析的 Java 进程号记为 $pid # 2) 查看进程加载的 libjvm.so 所在位置记为 $path grep libjvm.so /proc/$pid/maps # 3) 检查该文件是否包含符号表 readelf -WS $path | grep symtab配置方式配置前需要注意deepflow-agent 的 ConfigMap 仅用于 agent 向 server 注册而下方的 agent 自身配置需要通过 deepflow-ctl 下发。注CPU 剖析还有一些未出现在下方示例中的参数。如果你不确定修改后会产生什么影响建议保持默认值。inputs: proc: enabled: true process_matcher: # 功能列表默认开关参考链接中的详细描述 # https://www.deepflow.io/docs/zh/configuration/agent/#inputs.proc.process_matcher.enabled_features - enabled_features: - ebpf.profile.on_cpu - proc.gprocess_info # Rust 正则规则 # https://regex101.com/ match_regex: \bjava( \S)* -jar (\S*/)*([^ /]\.jar) # 匹配形式参考详细描述 # https://www.deepflow.io/docs/zh/configuration/agent/#inputs.proc.process_matcher match_type: cmdline_with_args # 是否仅匹配容器内的进程 # https://www.deepflow.io/docs/zh/configuration/agent/#inputs.proc.process_matcher.only_in_container only_in_container: false # 将匹配到的第三段 ([^ /]\.jar) 内容作为名称一般为 jar 包名 # 例如shop-web-0.0.1-SNAPSHOT.jar rewrite_name: $3 - enabled_features: - ebpf.profile.on_cpu - proc.gprocess_info - proc.socket_list match_regex: ^(cartservice|checkoutservice|shippingservice|coredns|mysqld|deepflow-server|deepflow-agent|stress-ng|cpu-demo) only_in_container: false校验结果查看当前的 Java Demo PIDrootce-demo-1:~# kubectl get pods -n deepflow-otel-spring-demo web-shop-7c48fd68dc-szchh -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES web-shop-7c48fd68dc-szchh 1/1 Running 0 83d 10.244.228.165 ce-demo-2 none none rootce-demo-1:~# kubectl exec -n deepflow-otel-spring-demo web-shop-7c48fd68dc-szchh -c web-shop -- ps aux PID USER TIME COMMAND 1 root 0:00 sh /home/docker-entrypoint.sh -javaagent:/sidecar/agent/opentelemetry-javaagent.jar -Dotel.resource.attributesservice.nameshop-web -Dotel.traces.exporterotlp -Dotel.metrics.exporternone -jar /home/shop-web-0.0.1-SNAPSHOT.jar 7 root 1d13 java -javaagent:/sidecar/agent/opentelemetry-javaagent.jar -Dotel.resource.attributesservice.nameshop-web -Dotel.traces.exporterotlp -Dotel.metrics.exporternone -jar /home/shop-web-0.0.1-SNAPSHOT.jar rootce-demo-1:~# ssh ce-demo-2 ps aux | grep shop-web-0.0.1-SNAPSHOT.jar root 2684642 2.0 2.4 8348252 406656 ? Sl 2025 2430:21 java -javaagent:/sidecar/agent/opentelemetry-javaagent.jar -Dotel.resource.attributesservice.nameshop-web -Dotel.traces.exporterotlp -Dotel.metrics.exporternone -jar /home/shop-web-0.0.1-SNAPSHOT.jar在 ClickHouse 中通过上一步的 PID 查询 DeepFlow 标签信息rootce-demo-1:~# kubectl exec -it -n deepflow deepflow-clickhouse-0 -c clickhouse -- bash rootdeepflow-clickhouse-0:/# clickhouse client ClickHouse client version 23.10.4.25 (official build). Connecting to localhost:9000 as user default. Connected to ClickHouse server version 23.10.4 revision 54466. deepflow-clickhouse-0.deepflow-clickhouse-headless.deepflow.svc.cluster.local :) -- 通过 PID 查询对应进程在 DeepFlow 中的 tag 信息 SELECT gprocess_id, app_service FROM profile.in_process WHERE process_id 2684642 LIMIT 1; ┌─gprocess_id─┬─app_service─┐ │ 123 │ java │ └─────────────┴─────────────┘ -- 通过 gprocess_id 查询 rewrite_name 是否生效 SELECT * FROM flow_tag.gprocess_map WHERE id 123 LIMIT 1; ┌──id─┬─name────────────────────────┬─icon_id─┬─chost_id─┬─l3_epc_id─┬─team_id─┬─domain_id─┬─sub_domain_id─┐ │ 123 │ shop-web-0.0.1-SNAPSHOT.jar │ 0 │ 2 │ 1 │ 1 │ 1 │ 0 │ └─────┴─────────────────────────────┴─────────┴──────────┴───────────┴─────────┴───────────┴───────────────┘查看 Continuous Profiling Dashboard 中对应 Demo 的剖析效果字段说明auto_service举例说明目前业务部署方式为 Deployment此处依据 k8s svc name deployment name 填写函数类型对应关系Function Type含义Profile Event Type特征O对象类型mem-*Memory Profile 的叶子节点H云主机*等于Total的根节点P进程*以[p]开头且不等于Total的根节点T线程*以[t]开头K内核函数*以[k]开头CCUDA 驱动函数*以[c]开头L动态链接库函数*以[l]开头?未知函数*其他以[开头A应用函数*除以上之外的函数

更多文章