一、为什么可观测性是第一生产力

在现代运维和性能调优体系中,可观测性(Observability) 是定位生产环境问题的第一道关口。传统监控关注「已知问题」的阈值告警,而可观测性关注「未知问题」的根因追溯。Linux 内核作为操作系统核心,其可观测性工具栈经历了从 strace 到 perf,再到 eBPF 的三次技术跃迁。

本文将从实战出发,覆盖 CPU、内存、IO、网络四大维度的观测工具栈,最终深入 eBPF 内核编程的生产级落地。

二、CPU 观测:从采样到火焰图

2.1 perf — 内核自带的全能采样器

perf 是 Linux 内核内置的性能分析工具,基于硬件性能计数器(PMC),几乎零开销。

# CPU 级采样,生成调用图
perf record -g -F 99 -p $(pidof java) -- sleep 30
perf report --stdio

# 查看热路径(Hot Path)
perf top -p $(pidof mysqld)

# 统计系统调用
perf trace -p 12345

# 火焰图生成
perf script | FlameGraph/stackcollapse-perf.pl | FlameGraph/flamegraph.pl > cpu.svg

2.2 turbostat — 睿频与 C-State 分析

# 每 2 秒采样所有核心
turbostat --interval 2 --show Core,CPU,Avg_MHz,Busy%,Bzy_MHz,TSC_MHz,CoreTmp,PkgWatt

当发现 Avg_MHz 低于标称频率且 Busy% 较高时,需排查散热策略或电源管理限制。

2.3 bpftop — 实时 eBPF 程序观测

bpftop        # 类似 top,显示运行中的 eBPF 程序及其 CPU 占用

三、内存观测:四层分析模型

3.1 用户态内存:valgrind massif + smaps

smem -r -k -P java                    # 按进程排序查看 RSS/USS/PSS
cat /proc//smaps | grep -E '^(Private|Swap|Rss)'  # 进程级内存映射

3.2 内核 Slab 分配器:slabtop + /proc/slabinfo

slabtop -s c -o | head -30            # 查看 slab 缓存占用

# dentry 缓存膨胀诊断(常见 OOM 陷阱)
grep dentry /proc/slabinfo
# 清理 slab(仅测试环境)
echo 3 > /proc/sys/vm/drop_caches

3.3 NUMA 拓扑感知:numastat + numactl

numastat -cm                           # 各 NUMA 节点内存使用
numactl --hardware                     # 查看 NUMA 拓扑
numastat -p $(pidof java)              # 进程级 NUMA 命中率

交叉访问(numa_miss 偏高)会导致内存延迟剧增,需通过 numactl --cpunodebind 绑核。

3.4 vmstat — 内存压力一站式视图

vmstat 1 10
# 关键列:si(swap in)、so(swap out)、free、buff、cache、si/so 非零即告警

四、存储 IO 观测:全栈追踪链路

4.1 iostat + iotop 快速定位

iostat -xz 1               # -x 扩展统计,-z 跳过空设备
# 关键指标:%util、await、avgqu-sz、r/s+w/s

iotop -oPa                  # 只显示有 IO 的进程,累计总量

4.2 blktrace + blkparse — 块设备层深度追踪

# 追踪读操作(耗时超过 50ms)
blktrace -d /dev/nvme0n1 -w 10 &
sleep 10 && kill %1
blkparse -i nvme0n1.blt -f "%D %2c %8s %5T.%9t %2p %S %n\n" | awk '$6==\"R\" && $4>50 {print}'

4.3 biolatency (BCC) — IO 延迟直方图

/usr/share/bcc/tools/biolatency 5 3    # 5 秒间隔,共 3 次
# 输出 2 次幂直方图,可发现长尾 IO

五、网络观测:从套接字到数据包

5.1 ss — netstat 的现代替代

ss -tlnp | grep LISTEN         # TCP 监听端口
ss -tn state established '( dport = :443 )' | wc -L   # 活跃 HTTPS 连接数
ss -ti                          # TCP CPI(cwnd/rtt)
ss -mop                        # socket 内存使用

5.2 nethogs + iftop — 带宽溯源

nethogs eth0 -t                # 按进程统计带宽
iftop -i eth0 -P               # 实时连接级流量

5.3 tcpdump — 经典抓包

# 抓取慢查询(RTT > 100ms)特征报文
tcpdump -i eth0 -nn 'tcp[tcpflags] & (tcp-syn|tcp-fin) != 0'
# 抓取 8080 端口 HTTP 500 响应(粗略过滤)
tcpdump -i eth0 -A 'tcp port 8080 and tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x48545450'

5.4 tcplife (BCC) — 连接生命周期

/usr/share/bcc/tools/tcplife -T              # PID/TID/寿命/字节数/事件
# 可用于识别短连接风暴

六、eBPF 革命:内核级可编程观测

6.1 eBPF 架构概览

eBPF 通过 BPF_PROG_LOAD 系统调用将用户态编译的字节码加载到内核,经过验证器(Verifier)安全检查后挂载到 Tracepoint/Kprobe/Tracepoint/USDT 等钩子点,通过 Ring Buffer/Perf Event 向用户态输出事件流。

用户态                    内核空间
┌──────────┐          ┌───────────────┐
│ 编写 C   │  verify  │ Tracepoint    │ → Ring Buffer → BPF Maps
│ 编译 LLVM ├────────→┤ Kprobe        │
│ 加载 prog │          │ XDP/skb hooks │
│ 读取 maps │←─────────┘
└──────────┘   perf_event_read

6.2 bpftrace — 单行脚本利器

# 追踪 accept() 调用分布
bpftrace -e 'tracepoint:syscalls:sys_enter_accept { @[comm] = count(); }'

# 统计 read() 延迟直方图(纳秒级)
bpftrace -e 'tracepoint:syscalls:sys_enter_read { @start[tid] = nsecs; }
  tracepoint:syscalls:sys_exit_read /@start[tid]/ { @us = hist((nsecs-@start[tid])/1000); }'

# 追踪所有文件打开
bpftrace -e 'tracepoint:syscalls:sys_enter_openat { printf("%s %s\n", comm, str(args->filename)); }'

# 调度器延迟
bpftrace -e 'tracepoint:sched:sched_switch { @[kstack, comm] = count(); }'

6.3 BCC (BPF Compiler Collection) — Python/Lua 接口

# 运行内置工具
/usr/share/bcc/tools/offcputime -K -p $(pidof java) 5    # 内核态 off-CPU
/usr/share/bcc/tools/biosnoop                            # 逐 IO 追踪
/usr/share/bcc/tools/tcpconnect                           # 新 TCP 连接追踪
/usr/share/bcc/tools/mdflush                             # 块层 flush 追踪
/usr/share/bcc/tools/syscount -P 'do_nanosleep'          # 系统调用统计

6.4 libbpf + CO-RE — 生产级 eBPF 开发

CO-RE(Compile Once - Run Everywhere) 解决了传统 eBPF 需要目标机器编译的痛点。通过 BTF(BPF Type Format)和重定位信息,编译后的 eBPF 字节码可跨内核版本运行。

// 最小 eBPF 程序:追踪 execve 调用
// SPDX-License-Identifier: GPL-2.0
#include "vmlinux.h"
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>

struct {
    __uint(type, BPF_MAP_TYPE_RINGBUF);
    __uint(max_entries, 256 * 1024);
} events SEC(".maps");

struct event {
    u32 pid;
    char comm[16];
    char filename[256];
};

SEC("tp/syscalls/sys_enter_execve")
int trace_execve(struct trace_event_raw_sys_enter *ctx) {
    struct event *e;
    e = bpf_ringbuf_reserve(&events, sizeof(*e), 0);
    if (!e) return 0;
    e->pid = bpf_get_current_pid_tgid() >> 32;
    bpf_get_current_comm(&e->comm, sizeof(e->comm));
    bpf_probe_read_user_str(&e->filename, sizeof(e->filename), (void *)ctx->args[0]);
    bpf_ringbuf_submit(e, 0);
    return 0;
}

char _license[] SEC("license") = "GPL";

七、生产级可观测性架构

7.1 Grafana + Prometheus + node_exporter

node_exporter 提供基础主机指标(CPU/内存/IO/网络),配合 Prometheus 的 PromQL 实现告警。但对于内核深度追踪(锁竞争、调度延迟、内存碎片),仍需 eBPF 方案补充。

7.2 Pixie / Hubble — Kubernetes 可观测性

Pixie 内置 eBPF 数据采集,自动抓取 HTTP/gRPC/DNS/Kafka/RabbitMQ 等协议流量,无需修改应用代码。Cilium/Hubble 则提供 L3-L7 网络可观测性和安全策略。

7.3 Katetrina / Parca — 持续性能分析

Parca 以 10s 采样+存储 的方式实现持续性能分析(Continuous Profiling),对比火焰图可发现低 CPU 使用率下的隐性热点。

八、生产环境实战案例

Case 1: 容器 CPU Throttling 定位

现象:容器化应用响应时间突增,top 显示 CPU 使用率不足 30%。

诊断:

kretprobe:pstat + cpu_throttled_time (BCC)
# 发现 latency = cpu_throttled_time / period_quota
# 解决:调整 cgroup cpu.cfs_quota_us

Case 2: 内存泄漏精确定位

现象:RSS 持续增长,free 不减少,重启后缓解。

诊断:

/usr/share/bcc/tools/memleak -p $(pidof java) -o 60000
# 输出分配调用栈和增长速率
# 最终定位到第三方库未释放 SSL session

Case 3: 网络抖动根因

现象:跨 AZ RTT 周期性跳变 5ms→50ms。

诊断:

/usr/share/bcc/tools/tcplife -L 0
# 锁定到 conntrack 表满触发 RTF_DROP
# 解决:调整 net.nf_conntrack_max + 使用 NOTRACK 规则

九、工具选型速查表

场景推荐工具原理
CPU 热点perf + flamegraphPMU 中断采样
内存泄漏memleak (BCC)kprobe kmalloc/kfree
IO 延迟biolatency (BCC)block_rq_issue/completion
网络抖动tcplife (BCC)kprobe tcp_set_state
系统调用strace / bpftraceptrace / tracepoint
持续分析Parca / PyroscopeeBPF profiler

十、总结与展望

Linux 可观测性工具栈已经进入 eBPF-first 时代。相比用户态工具,eBPF 具备三大优势:(1) 内核态执行,零上下文切换开销;(2) 可编程性,按需定制观测逻辑;(3) 安全验证,Verifier 保证不崩溃内核。

随着 eBPF 在容器网络(Cilium)、安全(Tetragon)、可观测性(Pixie)等场景的规模化落地,未来运维将从「被动告警」全面转向「主动可观测」,内核不再是黑盒,而是可编程的透明基础设施。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部