使用 Datakit 的 C/C++ profiling 功能
Datakit 的 C/C++ profiling 功能目前是基于 Pyroscope 的 eBPF 做的, 所以确切的来说应该叫 "eBPF Profiling"。
nginx 是一款用 C 语言编写的高性能的 HTTP 和反向代理 Web 服务器, 所以我们这里拿它来做 profiling 测试。
前置条件
Datakit 侧配置
将 Datakit 安装目录下 conf.d/profile/profile.conf.sample
复制为一份新的文件 conf.d/profile/profile.conf
, 内容如下(省略了 go 采集器的部分):
# {"version": "1.5.3-510-g8a072bf967", "desc": "do NOT edit this line"}
[[inputs.profile]]
## profile Agent endpoints register by version respectively.
## Endpoints can be skipped listen by remove them from the list.
## Default value set as below. DO NOT MODIFY THESE ENDPOINTS if not necessary.
endpoints = ["/profiling/v1/input"]
## set true to enable election, pull mode only
# election = true
# pyroscope config
[[inputs.profile.pyroscope]]
# listen url
url = "0.0.0.0:4040"
# service name
service = "pyroscope-demo"
# app env
env = "dev"
# app version
version = "0.0.0"
[inputs.profile.pyroscope.tags]
tag1 = "val1"
启动 Datakit。
Pyroscope Agent 侧的安装与配置
安装 Pyroscope Agent
以 Linux AMD64 平台为例:
wget https://dl.pyroscope.io/release/pyroscope-0.36.0-linux-amd64.tar.gz
tar -zxvf pyroscope-0.36.0-linux-amd64.tar.gz
按照上述方法获取到的是 Pyroscope 的二进制文件, 直接运行就可以了, 也可以放在 PATH 下。
其它平台与架构的安装方法, 见下载地址。
获取 nginx 的 PID
我测试机运行的是 Debian server, 获取 nginx 的 PID 命令如下:
$ sudo systemctl status nginx
● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/lib/systemd/system/nginx.service; disabled; vendor preset: enabled)
Active: active (running) since Thu 2023-01-19 14:24:08 CST; 4s ago
Docs: man:nginx(8)
Process: 789 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
Process: 790 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
Main PID: 791 (nginx)
Tasks: 3 (limit: 2264)
Memory: 11.3M
CPU: 37ms
CGroup: /system.slice/nginx.service
├─791 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
├─792 nginx: worker process
└─793 nginx: worker process
其中的 Main PID
就是 nginx 的主进程 PID, 即 791
, 捕获它就可以了。
运行 Pyroscope Agent
首先设置环境变量:
export PYROSCOPE_APPLICATION_NAME='my.ebpf.program{host=server-node-1,region=us-west-1,tag2=val2}'
export PYROSCOPE_SERVER_ADDRESS='http://localhost:4040/' # Datakit profile 配置的 pyroscope listen url.
export PYROSCOPE_SPY_NAME='ebpfspy'
捕获需要 root 权限。由于 nginx 的正在运行的进程, 所以使用命令:
$ sudo -E pyroscope connect --pid 791
此时,Pyroscope Agent 就会定时采样 nginx 主进程并将采样信息推送给 Datakit。
由于我们需要 profiling nginx,最好给 nginx 一些程序活动,比如我们可以给 nginx 做一些压力测试。下面这个脚本可以定时向 nginx 发起压力测试:
$ cat loop_nginx.sh
#!/bin/sh
while true;do
ab -n 10000 -c 100 http://127.0.0.1/
sleep 1
done
提示: 我们用上述命令运行的 Pyroscope Agent 是会一直定时采样的,不会主动退出。若要终止采样可以杀死 Pyroscope Agent 进程或者目标进程,这里的 "目标进程" 是 nginx。
登录观测云查看效果
稍等几分钟后就可以在观测云 空间应用性能监测 -> Profile 查看相应数据:
结语
总体来说, 由于 Datakit 是基于 Pyroscope eBPF 做的 profiling, 只是外在挂载, 没有代码侵入, 适合于偏网络程序的内核分析。
毕竟对于 profiling 来说, "代码侵入型" 的更适合程序内部细节分析, 而 "非代码侵入型" 的更适合做外在的内核分析。