Ubuntu运维日常监控的核心不是装一堆工具然后看图表,而是要搞清楚三件事:内核参数当前状态是否合理、进程行为是否异常、资源瓶颈到底卡在哪里。具体来说,你需要关注CPU调度、内存回收策略、I/O调度算法、网络连接跟踪、进程调度延迟这些内核层面的指标,同时配合top、htop、vmstat、iostat、sar、perf、bpftrace等工具对进程级行为做深度分析。下面我把这套体系从头到尾拆开讲,每一块都给你具体命令和调优思路。
一、内核参数监控:从sysctl到/proc的全面摸底
Ubuntu的内核参数默认配置是通用型的,生产环境几乎一定要调。第一步就是把当前所有内核参数导出来看一遍:
sysctl -a > /tmp/kernel_params_before.txt
重点关注以下几类参数。第一类是内存管理相关:vm.swappiness默认值是60,意味着内核比较积极地把内存页换到swap。如果你的服务器跑的是数据库或者Java应用,建议调到10甚至1:
sysctl vm.swappiness=10 echo "vm.swappiness=10" >> /etc/sysctl.conf
第二类是网络相关:net.core.somaxconn默认128,高并发场景下连接队列容易满,建议调到65535;net.ipv4.tcp_max_syn_backlog默认128,同样需要拉高到65535;net.ipv4.tcp_tw_reuse设为1可以快速回收TIME_WAIT连接:
sysctl -w net.core.somaxconn=65535 sysctl -w net.ipv4.tcp_max_syn_backlog=65535 sysctl -w net.ipv4.tcp_tw_reuse=1
第三类是文件描述符和进程限制:fs.file-max决定系统级别最大打开文件数,建议设为1000000以上;fs.nr_open是单个进程的文件描述符上限,默认1048576通常够用但要确认:
sysctl -w fs.file-max=2097152 sysctl -w fs.nr_open=1048576
这些参数不是改一次就完事,要定期用sysctl -a对比,防止被其他脚本或者内核升级覆盖。同时建议用/etc/sysctl.d/目录下的独立配置文件管理,方便版本控制和审计。
二、CPU监控与进程行为分析:不只是看使用率
很多人用top只看CPU%列,这远远不够。你要关注的是负载均衡(Load Average)、上下文切换(Context Switch)、进程调度延迟(Scheduling Latency)和CPU窃取(Steal Time)。vmstat 1可以实时看到这些:
vmstat 1 procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 2 0 0 8392432 245760 4521344 0 0 0 0 234 567 12 3 85 0 0
其中cs列是每秒上下文切换次数,如果持续超过50000就要警惕,说明进程间竞争激烈。r列是运行队列长度,超过CPU核数就意味着有进程在排队。us+sy超过80%说明CPU已经比较紧张,需要进一步用pidstat定位具体进程:
pidstat -u 1
更硬核的做法是用perf做采样分析,直接看内核态和用户态的热点函数:
perf top -g
这个命令会实时显示哪些内核函数占用CPU最多,比如你发现ext4_file_read_iter或者tcp_v4_rcv占比很高,就知道I/O或网络是瓶颈。对于进程行为异常,比如某个进程CPU突然飙高但top里看不到明显原因,可以用strace跟踪系统调用:
strace -p <PID> -c -f
-c参数会统计每个系统调用的耗时和次数,-f会跟踪子进程。如果发现大量futex或者epoll_wait调用,说明进程在等锁或者网络事件,需要从应用层排查。
三、内存监控:从free到slab的全链路追踪
free -h只能看到大致的内存使用情况,但真正的问题往往藏在细节里。你要同时看几个维度:可用内存(available)、缓冲区(buffers)、缓存(cache)、Slab占用、HugePages使用情况。用slabtop可以看到内核对象缓存的分布:
slabtop -o
如果发现dentry或者inode_cache占用异常高,可能是文件系统元数据过多,需要清理或者调整挂载参数。另外,/proc/meminfo里的SReclaimable和SUnreclaim两项要重点关注,前者是可以回收的Slab,后者是不能回收的,如果SUnreclaim持续增长说明有内存泄漏嫌疑。
对于Java、Python这类有自己内存管理的应用,还要监控/proc/<PID>/status里的VmRSS、VmSize、VmSwap,以及通过smaps看具体内存段的映射:
cat /proc/<PID>/smaps_rollup
如果某个进程的Anonymous内存段异常膨胀,基本可以判断是应用层内存泄漏,需要配合jmap、pympler或者valgrind做进一步定位。
四、磁盘I/O监控:iostat与iotop的组合拳
磁盘是最容易被忽视但最容易出问题的环节。iostat -xz 1可以看到每个磁盘的util、await、r/s、w/s、rMB/s、wMB/s。util接近100%说明磁盘已经饱和,await超过20ms对于SSD来说偏高,超过50ms对于HDD来说基本不可用:
iostat -xz 1 Device rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util sda 0.00 5.23 3.45 12.34 138.00 493.60 79.42 0.85 53.78 4.23 64.12 3.12 17.56
iotop -o可以看到具体哪个进程在吃I/O,配合--accumulated参数可以看到累计I/O量。如果发现某个进程持续大量写操作但你不知道原因,用lsof看它打开了哪些文件:
lsof -p <PID> | grep -v "^COMMAND"
对于I/O调度算法,Ubuntu默认用mq-deadline或者none(对于NVMe),可以用cat /sys/block/sda/queue/scheduler查看和切换。数据库场景推荐用none或noop减少调度开销,通用场景用mq-deadline比较均衡。
五、网络监控:从ss到tcpdump的多层透视
网络问题排查要分三层:连接状态、流量统计、包级分析。ss -s可以快速看到连接数汇总,包括ESTAB、TIME-WAIT、CLOSE-WAIT的数量:
ss -s Total: 1245 TCP: 890 (estab 45, closed 312, orphaned 0, synrecv 0, timewait 310/0), ports 0 Transport Total IP IPv6 * 890 - - RAW 0 0 0 UDP 12 8 4 TCP 878 870 8 INET 890 878 12 FRAG 0 0 0
TIME-WAIT过多说明连接回收慢,除了前面提到的tcp_tw_reuse,还要检查tcp_fin_timeout是否合理,默认60秒可以降到15秒。CLOSE-WAIT过多说明应用层没有正确关闭连接,这是代码问题。用iftop或nload看实时带宽,用nethogs看每个进程的网络用量。
真遇到丢包或者延迟问题,tcpdump是终极武器:
tcpdump -i eth0 -nn port 80 -c 1000
抓包后用wireshark分析,或者直接用tcpdump的统计模式:
tcpdump -i eth0 -nn -c 5000 | awk '{print $1}' | sort | uniq -c | sort -rn这条命令会统计每个源IP的包数量,快速定位异常流量来源。
六、进程行为深度分析:perf、bpftrace与eBPF的实战
传统工具能看到"什么进程占用了什么资源",但看不到"为什么"。这时候需要eBPF工具链。bpftrace是目前最好用的动态追踪工具,可以在不重启服务的情况下内核级观测。比如你想看哪些进程打开了超过1000个文件:
bpftrace -e 'tracepoint:syscalls:sys_enter_openat { @files[comm] = count(); }'想看进程的CPU调度延迟分布:
bpftrace -e 'tracepoint:sched:sched_switch { @us[comm] = hist(nsecs); }'perf record + perf report可以做离线采样分析,适合抓一段时间的数据再慢慢看:
perf record -a -g -p <PID> -- sleep 30 perf report
这些工具组合起来,基本可以覆盖从宏观到微观的所有进程行为分析需求。关键是要建立基线,正常状态下跑一遍这些命令,把输出存下来,出问题时对比就能快速定位。
七、自动化监控与告警体系搭建
手动跑命令不是长久之计,必须上自动化。Prometheus + node_exporter是目前最主流的方案,node_exporter能暴露几百个指标,覆盖CPU、内存、磁盘、网络、文件系统、内核参数等方方面面。配合Grafana做可视化,设置合理的告警阈值。关键指标的告警建议:CPU使用率持续5分钟超过80%告警、可用内存低于10%告警、磁盘util超过85%告警、TIME-WAIT超过5000告警、负载超过CPU核数2倍告警。
另外建议写几个自定义脚本做补充监控,比如用cron每5分钟跑一次vmstat和iostat,异常时自动发通知。把所有监控数据和调优记录归档,形成运维知识库,下次遇到类似问题直接查历史方案,效率会高很多。
总结一下,Ubuntu运维监控不是单一工具的事,而是一套从内核参数到进程行为、从实时监控到离线分析的完整体系。内核参数调优解决的是"地基"问题,进程行为分析解决的是"楼上哪户在漏水"的问题,两者缺一不可。把这套东西跑通了,你的服务器稳定性会上一个大台阶。
