从问题定位到性能调优 - 掌握网络调试的终极武器
系列:Linux 网络子系统源码剖析篇号:第 15 篇 (完结篇)内核版本:Linux 5.10 LTS重点模块:调试工具、性能分析、问题定位、故障排查
约 90-100 分钟
网络问题的复杂性:
多层次:

多组件:
动态性:
按层次分类:

按功能分类:
ping - ICMP 测试:
# 基本用法ping -c 4 8.8.8.8# 指定包大小ping -s 1400 8.8.8.8# 指定间隔ping -i 0.2 8.8.8.8# 记录路由ping -R 8.8.8.8# 设置 TTLping -t 64 8.8.8.8# 洪水 ping(需要 root)ping -f 8.8.8.8# 统计信息ping -c 100 8.8.8.8 | tail -2traceroute - 路由跟踪:
# 基本用法traceroute 8.8.8.8# 使用 ICMPtraceroute -I 8.8.8.8# 使用 TCPtraceroute -T -p 80 8.8.8.8# 不解析主机名traceroute -n 8.8.8.8# 设置最大跳数traceroute -m 20 8.8.8.8# 并行探测traceroute -N 16 8.8.8.8mtr - 持续路由跟踪:
# 交互式模式mtr 8.8.8.8# 报告模式mtr -r -c 100 8.8.8.8# 使用 TCPmtr -T -P 80 8.8.8.8# 显示 AS 号mtr -z 8.8.8.8# JSON 输出mtr -j -c 10 8.8.8.8tcpdump - 抓包工具:
# ========== 基本用法 ========== ## 抓取所有流量tcpdump -i eth0# 抓取指定数量的包tcpdump -i eth0 -c 100# 保存到文件tcpdump -i eth0 -w capture.pcap# 从文件读取tcpdump -r capture.pcap# ========== 过滤器 ========== ## 主机过滤tcpdump -i eth0 host 192.168.1.1# 网络过滤tcpdump -i eth0 net 192.168.1.0/24# 端口过滤tcpdump -i eth0 port 80# 协议过滤tcpdump -i eth0 tcptcpdump -i eth0 udptcpdump -i eth0 icmp# 组合过滤tcpdump -i eth0 'tcp port 80 and host 192.168.1.1'tcpdump -i eth0 'tcp[tcpflags] & tcp-syn != 0'# ========== 高级选项 ========== ## 显示详细信息tcpdump -i eth0 -vtcpdump -i eth0 -vvtcpdump -i eth0 -vvv# 显示十六进制和 ASCIItcpdump -i eth0 -X# 不解析主机名和端口tcpdump -i eth0 -nn# 显示绝对时间戳tcpdump -i eth0 -tttt# 抓取完整包(不截断)tcpdump -i eth0 -s 0# ========== 实用示例 ========== ## 抓取 HTTP 请求tcpdump -i eth0 -A 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)'# 抓取 SYN 包tcpdump -i eth0 'tcp[tcpflags] & tcp-syn != 0'# 抓取 DNS 查询tcpdump -i eth0 -n port 53# 抓取大包(>1000 字节)tcpdump -i eth0 'greater 1000'# 抓取特定 MAC 地址tcpdump -i eth0 ether host 00:11:22:33:44:55Wireshark/tshark - 图形化抓包:
# tshark 命令行用法# 基本抓包tshark -i eth0# 使用显示过滤器tshark -i eth0 -Y 'tcp.port == 80'# 统计信息tshark -i eth0 -z io,stat,1# 协议层次统计tshark -i eth0 -z io,phs# 会话统计tshark -i eth0 -z conv,tcp# 导出对象tshark -r capture.pcap --export-objects http,./output/# JSON 输出tshark -i eth0 -T json# 字段提取tshark -r capture.pcap -T fields -e ip.src -e ip.dst -e tcp.portss - Socket 统计:
# ========== 基本用法 ========== ## 显示所有 socketss -a# 显示监听 socketss -l# 显示 TCP socketss -t# 显示 UDP socketss -u# 显示进程信息ss -p# 显示详细信息ss -e# 不解析服务名ss -n# ========== 组合使用 ========== ## 显示所有 TCP 连接ss -tan# 显示监听的 TCP 端口ss -tln# 显示 ESTABLISHED 连接ss -tan state established# 显示 TIME-WAIT 连接ss -tan state time-wait# ========== 过滤 ========== ## 按端口过滤ss -tan sport = :80ss -tan dport = :3306# 按地址过滤ss -tan dst 192.168.1.1# 按状态过滤ss -tan state syn-sentss -tan state fin-wait-1# ========== 统计信息 ========== ## 汇总统计ss -s# 显示内存使用ss -m# 显示定时器ss -o# 显示 TCP 信息ss -ti# ========== 实用示例 ========== ## 查看连接最多的 IPss -tan | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr | head# 查看各状态的连接数ss -tan | awk '{print $1}' | sort | uniq -c# 查看 ESTABLISHED 连接的 RTTss -ti state established | grep rtt# 查看拥塞窗口ss -ti | grep cwndnetstat - 网络统计(传统工具):
# 显示所有连接netstat -an# 显示路由表netstat -rn# 显示接口统计netstat -i# 显示协议统计netstat -s# 显示多播组netstat -g# 持续监控netstat -cip - 网络配置:
# ========== 地址管理 ========== ## 显示所有地址ip addr show# 添加地址ip addr add 192.168.1.100/24 dev eth0# 删除地址ip addr del 192.168.1.100/24 dev eth0# ========== 链路管理 ========== ## 显示链路状态ip link show# 启动/关闭接口ip linkset eth0 upip linkset eth0 down# 设置 MTUip linkset eth0 mtu 9000# 设置 MAC 地址ip linkset eth0 address 00:11:22:33:44:55# ========== 路由管理 ========== ## 显示路由表ip route show# 添加路由ip route add 10.0.0.0/8 via 192.168.1.1# 删除路由ip route del 10.0.0.0/8# 添加默认路由ip route add default via 192.168.1.1# 查看路由ip route get 8.8.8.8# ========== 邻居表 ========== ## 显示 ARP 表ip neigh show# 添加静态 ARPip neigh add 192.168.1.1 lladdr 00:11:22:33:44:55 dev eth0# 删除 ARP 条目ip neigh del 192.168.1.1 dev eth0# ========== 统计信息 ========== ## 显示详细统计ip -s link show eth0# 持续监控ip -s -s link show eth0ethtool - 网卡配置:
# ========== 基本信息 ========== ## 显示网卡信息ethtool eth0# 显示驱动信息ethtool -i eth0# 显示统计信息ethtool -S eth0# ========== 速度和双工 ========== ## 设置速度和双工ethtool -s eth0 speed 1000 duplex full autoneg off# 自动协商ethtool -s eth0 autoneg on# ========== Offload 特性 ========== ## 显示 offload 特性ethtool -k eth0# 启用/禁用特性ethtool -K eth0 tso onethtool -K eth0 gro onethtool -K eth0 gso on# ========== 队列配置 ========== ## 显示队列数量ethtool -l eth0# 设置队列数量ethtool -L eth0 combined 4# 显示 ring 缓冲区大小ethtool -g eth0# 设置 ring 缓冲区ethtool -G eth0 rx 4096 tx 4096# ========== 中断合并 ========== ## 显示中断合并配置ethtool -c eth0# 设置中断合并ethtool -C eth0 rx-usecs 50 rx-frames 32# 启用自适应中断合并ethtool -C eth0 adaptive-rx on adaptive-tx on# ========== 测试 ========== ## 自检测试ethtool -t eth0# 闪烁 LEDethtool -p eth0 10ftrace 基础:
# ========== 启用 ftrace ========== ## 挂载 debugfs(如果未挂载)mount -t debugfs none /sys/kernel/debug# ftrace 目录cd /sys/kernel/debug/tracing# ========== 查看可用跟踪器 ========== #cat available_tracers# 输出:function_graph function nop# ========== 函数跟踪 ========== ## 启用函数跟踪echofunction > current_tracer# 设置过滤器(只跟踪网络相关函数)echo'tcp_*' > set_ftrace_filterecho'ip_*' >> set_ftrace_filter# 开始跟踪echo 1 > tracing_on# 查看跟踪结果cat trace# 停止跟踪echo 0 > tracing_on# 清空跟踪缓冲区echo > trace# ========== 函数图跟踪 ========== ## 启用函数图跟踪echo function_graph > current_tracer# 设置跟踪深度echo 5 > max_graph_depth# 设置图过滤器echo tcp_sendmsg > set_graph_function# 查看结果cat trace# ========== 事件跟踪 ========== ## 查看可用事件cat available_events | grep net# 启用特定事件echo 1 > events/net/netif_rx/enableecho 1 > events/net/net_dev_queue/enable# 启用所有网络事件echo 1 > events/net/enable# 查看事件格式cat events/net/netif_rx/format# ========== 实用脚本 ========== ## 跟踪 TCP 发送路径#!/bin/bashcd /sys/kernel/debug/tracingecho 0 > tracing_onecho > traceecho function_graph > current_tracerecho tcp_sendmsg > set_graph_functionecho 1 > tracing_onsleep 5echo 0 > tracing_oncat tracekprobe 使用:
# ========== 基本用法 ========== #cd /sys/kernel/debug/tracing# 添加 kprobeecho'p:myprobe tcp_sendmsg' > kprobe_events# 查看 kprobecat kprobe_events# 启用 kprobeecho 1 > events/kprobes/myprobe/enable# 查看结果cat trace# 禁用 kprobeecho 0 > events/kprobes/myprobe/enable# 删除 kprobeecho'-:myprobe' >> kprobe_events# ========== 高级用法 ========== ## 捕获参数echo'p:myprobe tcp_sendmsg size=%dx' > kprobe_events# 捕获返回值echo'r:myretprobe tcp_sendmsg ret=$retval' > kprobe_events# 捕获结构体字段echo'p:myprobe tcp_sendmsg sk=+0(%di):u64' > kprobe_events# 条件过滤echo'p:myprobe tcp_sendmsg size=%dx if size>1000' > kprobe_eventsbpftrace 脚本:
# ========== 跟踪网络发送 ========== ## 统计发送字节数bpftrace -e 'kprobe:dev_queue_xmit { @bytes = hist(arg0->len); }'# 跟踪 TCP 连接bpftrace -e 'kprobe:tcp_connect { printf("PID %d connecting to %s\n", pid, str(arg0));}'# 跟踪丢包bpftrace -e 'tracepoint:skb:kfree_skb { @drop[kstack] = count();}'# ========== 网络延迟分析 ========== ## TCP 发送延迟bpftrace -e 'kprobe:tcp_sendmsg { @start[tid] = nsecs;}kretprobe:tcp_sendmsg /@start[tid]/ { @latency = hist(nsecs - @start[tid]); delete(@start[tid]);}'# ========== 完整脚本示例 ========== ## tcp_life.bt - 跟踪 TCP 连接生命周期#!/usr/bin/env bpftraceBEGIN {printf("Tracing TCP connections... Hit Ctrl-C to end.\n");printf("%-8s %-16s %-6s %-16s %-6s %-8s\n","PID", "COMM", "LPORT", "RADDR", "RPORT", "DURATION");}kprobe:tcp_set_state {$sk = (struct sock *)arg0;$newstate = arg1;if ($newstate == 1) { /* TCP_ESTABLISHED */ @start[$sk] = nsecs; @lport[$sk] = $sk->__sk_common.skc_num; @rport[$sk] = $sk->__sk_common.skc_dport; @raddr[$sk] = $sk->__sk_common.skc_daddr; }if ($newstate == 7 && @start[$sk]) { /* TCP_CLOSE */$duration = (nsecs - @start[$sk]) / 1000000; /* ms */printf("%-8d %-16s %-6d %-16s %-6d %-8d\n", pid, comm, @lport[$sk], ntop(@raddr[$sk]), @rport[$sk], $duration); delete(@start[$sk]); delete(@lport[$sk]); delete(@rport[$sk]); delete(@raddr[$sk]); }}END { clear(@start); clear(@lport); clear(@rport); clear(@raddr);}dmesg - 内核消息:
# 查看所有消息dmesg# 持续监控dmesg -w# 按级别过滤dmesg -l err,warn# 按设施过滤dmesg -f kern# 显示时间戳dmesg -T# 清空缓冲区dmesg -c# 查看网络相关消息dmesg | grep -i 'eth0\|network\|tcp'printk 调试:
/* 在内核代码中添加调试信息 */#include<linux/printk.h>/* 不同级别的 printk */pr_emerg("Emergency message\n");pr_alert("Alert message\n");pr_crit("Critical message\n");pr_err("Error message\n");pr_warning("Warning message\n");pr_notice("Notice message\n");pr_info("Info message\n");pr_debug("Debug message\n");/* 网络相关的 printk */netdev_err(dev, "Device error: %d\n", err);netdev_warn(dev, "Device warning\n");netdev_info(dev, "Device info\n");netdev_dbg(dev, "Device debug\n");/* 条件 printk */pr_debug_ratelimited("Rate limited debug\n");pr_info_once("Print only once\n");perf 基础:
# ========== 系统级分析 ========== ## 记录系统性能数据perf record -a -g -- sleep 10# 查看报告perf report# 实时监控perf top# 指定事件perf top -e cyclesperf top -e instructionsperf top -e cache-misses# ========== 网络相关分析 ========== ## 记录网络事件perf record -e net:* -a -g -- sleep 10# 跟踪特定函数perf record -e probe:tcp_sendmsg -a -g# 记录调用栈perf record -a -g --call-graph dwarf# ========== 进程级分析 ========== ## 分析特定进程perf record -p <pid> -g -- sleep 10# 分析特定命令perf record -g ./my_program# ========== 统计信息 ========== ## 统计事件perf stat -e cycles,instructions,cache-misses ./program# 网络统计perf stat -e 'net:*' -a -- sleep 10# ========== 火焰图 ========== ## 生成火焰图perf record -F 99 -a -g -- sleep 60perf script | stackcollapse-perf.pl | flamegraph.pl > flame.svgperf 脚本示例:
#!/bin/bash# network_perf.sh - 网络性能分析脚本echo"Recording network performance for 30 seconds..."# 记录网络相关的性能数据perf record -e 'net:*' \ -e 'skb:*' \ -e 'tcp:*' \ -e 'udp:*' \ -a -g -- sleep 30# 生成报告echo"Generating report..."perf report --stdio > perf_report.txt# 生成火焰图echo"Generating flame graph..."perf script | stackcollapse-perf.pl | flamegraph.pl > network_flame.svgecho"Analysis complete!"echo"Report: perf_report.txt"echo"Flame graph: network_flame.svg"SystemTap 脚本示例:
#!/usr/bin/env stap# tcp_connections.stp - 跟踪 TCP 连接probe kernel.function("tcp_connect") { printf("%s[%d] connecting to %s:%d\n", execname(), pid(), ip_ntop($sk->__sk_common.skc_daddr), $sk->__sk_common.skc_dport);}probe kernel.function("tcp_set_state") { if ($state == 1) { /* TCP_ESTABLISHED */ printf("%s[%d] connection established\n", execname(), pid()); }}probe kernel.function("tcp_done") { printf("%s[%d] connection closed\n", execname(), pid());}iperf3 - 吞吐量测试:
# ========== 服务器端 ========== ## 启动服务器iperf3 -s# 指定端口iperf3 -s -p 5201# ========== 客户端 ========== ## TCP 测试iperf3 -c <server_ip># 指定时间iperf3 -c <server_ip> -t 60# 并行连接iperf3 -c <server_ip> -P 4# 反向测试(服务器发送)iperf3 -c <server_ip> -R# UDP 测试iperf3 -c <server_ip> -u -b 1G# 指定窗口大小iperf3 -c <server_ip> -w 256K# JSON 输出iperf3 -c <server_ip> -J > results.json# ========== 高级选项 ========== ## 设置 MSSiperf3 -c <server_ip> -M 1400# 设置 TOSiperf3 -c <server_ip> -S 0x10# 绑定到特定接口iperf3 -c <server_ip> -B eth0# 零拷贝iperf3 -c <server_ip> -Z问题描述:应用程序报告间歇性丢包。
排查步骤:
# ========== 1. 检查网卡统计 ========== ## 查看网卡错误ethtool -S eth0 | grep -i 'error\|drop\|discard'# 查看 RX/TX 队列丢包ethtool -S eth0 | grep -i 'rx.*drop\|tx.*drop'# 输出示例:# rx_dropped: 1234# tx_dropped: 0# ========== 2. 检查系统丢包 ========== ## 查看协议栈丢包netstat -s | grep -i drop# 查看 softnet 丢包cat /proc/net/softnet_stat# 第二列是丢包数# 查看 backlog 队列sysctl net.core.netdev_max_backlog# ========== 3. 检查防火墙 ========== ## 查看 iptables 丢包iptables -L -v -n | grep DROP# 查看 conntrack 表cat /proc/net/nf_conntrack | wc -lsysctl net.netfilter.nf_conntrack_max# ========== 4. 使用 dropwatch ========== ## 安装 dropwatchapt-get install dropwatch# 运行 dropwatchdropwatch -l kas# 输出会显示丢包的内核函数# ========== 5. 使用 eBPF 跟踪丢包 ========== ## 跟踪 kfree_skbbpftrace -e 'tracepoint:skb:kfree_skb { @drop[kstack] = count(); @reason[args->reason] = count();}interval:s:10 { print(@drop); print(@reason); clear(@drop); clear(@reason);}'解决方案:
# 根据排查结果采取措施# 1. 如果是 RX 队列丢包ethtool -G eth0 rx 4096# 2. 如果是 softnet 丢包sysctl -w net.core.netdev_max_backlog=5000sysctl -w net.core.netdev_budget=600# 3. 如果是 conntrack 表满sysctl -w net.netfilter.nf_conntrack_max=1048576# 4. 如果是中断不均衡./set_irq_affinity.sh eth0问题描述:TCP 连接建立缓慢。
排查步骤:
# ========== 1. 检查 SYN 队列 ========== ## 查看 SYN 队列溢出netstat -s | grep -i 'SYNs to LISTEN'# 查看半连接队列大小sysctl net.ipv4.tcp_max_syn_backlog# 查看全连接队列大小sysctl net.core.somaxconn# ========== 2. 检查 SYN Cookie ========== ## 查看 SYN Cookie 状态sysctl net.ipv4.tcp_syncookies# 查看 SYN Cookie 统计netstat -s | grep -i 'SYN cookies'# ========== 3. 使用 ss 查看队列 ========== ## 查看监听队列ss -ltn# 输出示例:# Recv-Q Send-Q Local Address:Port# 0 128 *:80# Recv-Q: 当前队列中的连接数# Send-Q: 最大队列长度# ========== 4. 跟踪连接建立 ========== ## 使用 tcpdump 抓取 SYN 包tcpdump -i eth0 'tcp[tcpflags] & tcp-syn != 0' -nn# 使用 bpftrace 跟踪bpftrace -e 'kprobe:tcp_v4_conn_request { printf("SYN received from %s\n", ntop(arg1));}kprobe:tcp_v4_syn_recv_sock { printf("Connection established\n");}'# ========== 5. 检查防火墙规则 ========== ## 查看 iptables 规则iptables -L -v -n# 查看 conntrack 连接数cat /proc/sys/net/netfilter/nf_conntrack_countcat /proc/sys/net/netfilter/nf_conntrack_max解决方案:
# 1. 增大队列sysctl -w net.ipv4.tcp_max_syn_backlog=8192sysctl -w net.core.somaxconn=4096# 2. 启用 SYN Cookiesysctl -w net.ipv4.tcp_syncookies=1# 3. 启用 TCP Fast Opensysctl -w net.ipv4.tcp_fastopen=3# 4. 调整应用程序 listen backlog# 在代码中:listen(sockfd, 4096);问题描述:网络延迟突然增高。
排查步骤:
# ========== 1. 基本延迟测试 ========== ## ICMP 延迟ping -c 100 <target> | tail -2# TCP 延迟ss -ti | grep rtt# ========== 2. 检查队列延迟 ========== ## 查看 qdisc 统计tc -s qdisc show dev eth0# 查看队列深度ip -s link show eth0# ========== 3. 检查 CPU 使用率 ========== ## 查看软中断 CPUmpstat -P ALL 1 | grep -E 'CPU|%soft'# 查看网络相关进程top -H -p $(pgrep -d',' ksoftirqd)# ========== 4. 跟踪数据包路径 ========== ## 使用 bpftrace 测量延迟bpftrace -e 'kprobe:netif_receive_skb { @start[arg0] = nsecs;}kprobe:ip_rcv /@start[arg0]/ { @latency["netif_rx -> ip_rcv"] = hist(nsecs - @start[arg0]);}kprobe:tcp_v4_rcv /@start[arg0]/ { @latency["ip_rcv -> tcp_rcv"] = hist(nsecs - @start[arg0]); delete(@start[arg0]);}'# ========== 5. 检查网卡配置 ========== ## 查看中断合并ethtool -c eth0# 查看队列数量ethtool -l eth0解决方案:
# 1. 减小中断合并延迟ethtool -C eth0 rx-usecs 10 rx-frames 8# 2. 使用 fq_codel qdisctc qdisc replace dev eth0 root fq_codel# 3. 启用 TCP_NODELAY# 在应用程序中设置# 4. 调整 CPU 亲和性./set_irq_affinity.sh eth0问题描述:网络吞吐量远低于预期。
排查步骤:
# ========== 1. 测试基准性能 ========== ## 使用 iperf3 测试iperf3 -c <server> -t 60 -P 4# ========== 2. 检查 TCP 窗口 ========== ## 查看 TCP 窗口大小ss -ti | grep -E 'wscale|rcv_space'# 查看 TCP 缓冲区配置sysctl net.ipv4.tcp_rmemsysctl net.ipv4.tcp_wmem# ========== 3. 检查拥塞控制 ========== ## 查看拥塞控制算法sysctl net.ipv4.tcp_congestion_control# 查看可用算法sysctl net.ipv4.tcp_available_congestion_control# 查看连接的拥塞窗口ss -ti | grep cwnd# ========== 4. 检查 Offload 特性 ========== ## 查看 TSO/GSO/GROethtool -k eth0 | grep -E 'tcp-segmentation|generic-segmentation|generic-receive'# ========== 5. 检查 MTU ========== ## 查看 MTUip link show eth0# 测试路径 MTUtracepath <target># ========== 6. 检查重传 ========== ## 查看重传统计netstat -s | grep -i retrans# 实时监控重传ss -ti | grep -E 'retrans|lost'解决方案:
# 1. 增大 TCP 缓冲区sysctl -w net.ipv4.tcp_rmem="4096 87380 16777216"sysctl -w net.ipv4.tcp_wmem="4096 65536 16777216"# 2. 启用 TCP 窗口缩放sysctl -w net.ipv4.tcp_window_scaling=1# 3. 切换拥塞控制算法sysctl -w net.ipv4.tcp_congestion_control=bbr# 4. 启用所有 Offloadethtool -K eth0 tso on gso on gro on# 5. 增大 MTU(如果支持)ip linkset eth0 mtu 9000自顶向下方法:
1. 应用层 ├─ 检查应用日志 ├─ 使用 strace 跟踪系统调用 └─ 检查 socket 选项2. 传输层 ├─ 使用 ss/netstat 查看连接状态 ├─ 检查 TCP 参数 └─ 分析重传和丢包3. 网络层 ├─ 检查路由表 ├─ 检查 iptables 规则 └─ 分析 IP 分片4. 链路层 ├─ 检查网卡状态 ├─ 查看网卡统计 └─ 检查 MTU5. 物理层 ├─ 检查链路状态 ├─ 检查错误计数 └─ 测试线缆连通性问题:
# 1. 基本连通性ping <target># 2. 路由跟踪traceroute <target># 3. DNS 解析nslookup <hostname>dig <hostname># 4. 端口测试telnet <target> <port>nc -zv <target> <port># 5. 抓包分析tcpdump -i eth0 host <target> -w capture.pcap性能问题:
# 1. 系统资源topmpstat -P ALL 1vmstat 1# 2. 网络统计ss -snetstat -s# 3. 网卡统计ethtool -S eth0ip -s link show eth0# 4. 性能测试iperf3 -c <server># 5. 性能分析perf record -a -gperf report网络诊断脚本:
#!/bin/bash# network_diag.sh - 网络诊断脚本OUTPUT_DIR="network_diag_$(date +%Y%m%d_%H%M%S)"mkdir -p "$OUTPUT_DIR"echo"Starting network diagnostics..."# ========== 1. 基本信息 ========== #echo"Collecting basic information..."uname -a > "$OUTPUT_DIR/system_info.txt"ip addr show > "$OUTPUT_DIR/ip_addr.txt"ip route show > "$OUTPUT_DIR/ip_route.txt"ip neigh show > "$OUTPUT_DIR/ip_neigh.txt"# ========== 2. 网卡信息 ========== #echo"Collecting interface information..."for iface in $(ls /sys/class/net/); doif [ "$iface" != "lo" ]; then ethtool "$iface" > "$OUTPUT_DIR/ethtool_${iface}.txt" 2>&1 ethtool -S "$iface" > "$OUTPUT_DIR/ethtool_stats_${iface}.txt" 2>&1 ethtool -k "$iface" > "$OUTPUT_DIR/ethtool_features_${iface}.txt" 2>&1fidone# ========== 3. 连接状态 ========== #echo"Collecting connection information..."ss -tan > "$OUTPUT_DIR/ss_tcp.txt"ss -uan > "$OUTPUT_DIR/ss_udp.txt"ss -s > "$OUTPUT_DIR/ss_summary.txt"# ========== 4. 统计信息 ========== #echo"Collecting statistics..."netstat -s > "$OUTPUT_DIR/netstat_stats.txt"cat /proc/net/softnet_stat > "$OUTPUT_DIR/softnet_stat.txt"cat /proc/net/sockstat > "$OUTPUT_DIR/sockstat.txt"# ========== 5. 防火墙规则 ========== #echo"Collecting firewall rules..."iptables -L -v -n > "$OUTPUT_DIR/iptables.txt" 2>&1iptables -t nat -L -v -n > "$OUTPUT_DIR/iptables_nat.txt" 2>&1# ========== 6. 系统参数 ========== #echo"Collecting sysctl parameters..."sysctl -a | grep -E 'net\.' > "$OUTPUT_DIR/sysctl_net.txt" 2>&1# ========== 7. 内核日志 ========== #echo"Collecting kernel logs..."dmesg | grep -i 'network\|eth\|tcp\|udp' > "$OUTPUT_DIR/dmesg_network.txt"# ========== 8. 进程信息 ========== #echo"Collecting process information..."ps aux | grep -E 'network|tcp|udp' > "$OUTPUT_DIR/processes.txt"# ========== 9. 创建摘要 ========== #echo"Creating summary..."cat > "$OUTPUT_DIR/summary.txt" << EOFNetwork Diagnostics SummaryGenerated: $(date)System: $(uname -a)Network Interfaces:$(ip -br addr show)Active Connections:$(ss -s)Top Network Processes:$(ps aux --sort=-%cpu | grep -E 'network|tcp|udp' | head -10)Recent Network Errors:$(dmesg | grep -i 'error\|fail' | grep -i 'network\|eth' | tail -20)EOFecho"Diagnostics complete! Results saved to: $OUTPUT_DIR"调试工具分类:
排查方法:
常见问题:
基础检查:
# 1. 网卡状态ip link showethtool eth0# 2. IP 配置ip addr showip route show# 3. 连接状态ss -tanss -s# 4. 统计信息netstat -sethtool -S eth0# 5. 系统参数sysctl -a | grep net.性能检查:
# 1. CPU 使用率mpstat -P ALL 1# 2. 中断分布cat /proc/interrupts | grep eth0# 3. 队列状态tc -s qdisc show# 4. Offload 特性ethtool -k eth0# 5. 缓冲区大小sysctl net.ipv4.tcp_rmemsysctl net.ipv4.tcp_wmem日常监控:
问题排查:
深度调试:
快速诊断流程:
# 1. 检查连通性(10 秒)ping -c 4 <target># 2. 检查路由(10 秒)traceroute -n <target># 3. 检查端口(5 秒)nc -zv <target> <port># 4. 检查本地状态(5 秒)ss -tan | grep <target># 5. 抓包分析(30 秒)tcpdump -i eth0 host <target> -c 100# 总计:约 1 分钟tcpdump:
Wireshark:
推荐组合:
# 服务器上用 tcpdump 抓包tcpdump -i eth0 -w capture.pcap# 下载到本地用 Wireshark 分析scp user@server:capture.pcap .wireshark capture.pcap延迟分析方法:
# 1. ICMP 延迟ping -c 100 <target> | tail -2# 2. TCP 延迟ss -ti | grep rtt# 3. 应用层延迟curl -w "@curl-format.txt" -o /dev/null -s <url># curl-format.txt:time_namelookup: %{time_namelookup}\ntime_connect: %{time_connect}\ntime_starttransfer: %{time_starttransfer}\ntime_total: %{time_total}\n# 4. 使用 bpftrace 测量内核延迟bpftrace -e 'kprobe:tcp_sendmsg { @start[tid] = nsecs;}kretprobe:tcp_sendmsg /@start[tid]/ { @latency = hist(nsecs - @start[tid]); delete(@start[tid]);}'丢包监控方法:
# 1. 网卡丢包watch -n 1 'ethtool -S eth0 | grep drop'# 2. 协议栈丢包watch -n 1 'netstat -s | grep -i drop'# 3. 队列丢包watch -n 1 'cat /proc/net/softnet_stat'# 4. 使用 dropwatchdropwatch -l kas# 5. 使用 eBPF 实时监控bpftrace -e 'tracepoint:skb:kfree_skb { @drop[kstack] = count();}interval:s:5 { print(@drop); clear(@drop);}'内核调试方法:
# 1. 添加 printk# 在内核代码中添加:pr_info("Debug: value=%d\n", value);# 重新编译内核make -j$(nproc)make modules_installmake install# 查看输出dmesg | tail# 2. 使用 ftraceecho function_graph > /sys/kernel/debug/tracing/current_tracerecho tcp_sendmsg > /sys/kernel/debug/tracing/set_graph_functionecho 1 > /sys/kernel/debug/tracing/tracing_on# 3. 使用 kprobeecho'p:myprobe tcp_sendmsg' > /sys/kernel/debug/tracing/kprobe_eventsecho 1 > /sys/kernel/debug/tracing/events/kprobes/myprobe/enable# 4. 使用 crash 分析崩溃crash /usr/lib/debug/vmlinux /var/crash/vmcore内核文档:
工具文档:
技术博客:
工具集合:
连通性测试:
ping, traceroute, mtr, nc, telnet流量分析:
tcpdump, wireshark, tshark, ngrep状态查看:
ss, netstat, ip, ethtool, ifconfig性能分析:
perf, iperf3, netperf, sar, vmstat内核跟踪:
ftrace, kprobe, bpftrace, SystemTap本系列共 15 篇文章,全面剖析了 Linux 网络子系统:
第一部分:基础架构(3 篇)
第二部分:协议栈实现(5 篇)4. 二层处理与网桥5. IP 层实现(上)- 接收与路由6. IP 层实现(下)- 发送与分片7. TCP 协议实现(上)- 连接管理8. TCP 协议实现(下)- 数据传输与拥塞控制
第三部分:高级特性(4 篇)9. Netfilter 与 iptables 源码解析10. 流量控制(QoS)源码解析11. 套接字层实现12. 网络命名空间(Network Namespace)
第四部分:性能优化(3 篇)13. 网络性能优化技术14. eBPF/XDP 网络加速15. 网络子系统调试技术
数据结构:
关键流程:
性能优化:
初学者:
进阶者:
高级用户:
系列完结
感谢您阅读《Linux 网络子系统源码剖析系列》!
本系列涵盖了从基础到高级的所有重要主题。希望这些内容能帮助您深入理解 Linux 网络子系统,在实际工作中解决问题,并激发您对内核开发的兴趣。
作者:肇中内核版本:Linux 5.10 LTS
勘误和建议:欢迎提出勘误和改进建议。
致谢:
祝您在 Linux 内核网络的学习和研究中取得成功!