当前位置: 代码网 > 服务器>服务器>Linux > Linux运维排查必会命令整理:从CPU内存到日志网络的实战手册

Linux运维排查必会命令整理:从CPU内存到日志网络的实战手册

2026年09月15日 Linux 我要评论
从事linux运维这些年,我发现自己每天敲得最多的,往往不是那些花哨的框架命令,而是几十个基础命令在不同场景下的组合套用。很多刚入行的朋友喜欢背“命令大全”,但真到服务器报警时

从事linux运维这些年,我发现自己每天敲得最多的,往往不是那些花哨的框架命令,而是几十个基础命令在不同场景下的组合套用。很多刚入行的朋友喜欢背“命令大全”,但真到服务器报警时,却不知道先敲哪条、输出该怎么看。这篇文章不打算做命令字典,而是按真实的运维排查链路,把那些必须刻进肌肉记忆的linux命令捋一遍——每个命令都配上实际场景和关键细节,希望能帮你少走点弯路。

1. 开局先看“老三样”:cpu、内存、磁盘的体检命令

接到服务器异常的反馈,我一般不做花哨操作,先登录上去执行三连: uptime free -h df -h 。这三条命令的成本极低,但能快速划定问题范围,是后续所有排查动作的起点。

1.1 uptime与load average的读取逻辑

uptime 输出里最容易被误读的是 load average: 2.50, 1.80, 1.20 。三个数字分别代表1分钟、5分钟、15分钟的平均负载。对于负载是否过高,不是简单地和cpu核数比大小,而是要看趋势:如果1分钟高于5分钟、5分钟高于15分钟,说明负载正在快速爬升;反之则说明系统在恢复。

这里有一个容易踩的坑:负载高不一定等于cpu忙。负载包含处于r状态(运行中)和d状态(不可中断睡眠)的进程数。如果cpu使用率不高但负载很高,往往是有进程卡在磁盘i/o或内核锁上,这时候去看 iostat top 里的wa列更有意义。我见过不少新手看到负载到4就急着加机器,结果最后定位是磁盘坏道引起的d状态进程堆积。

1.2 free命令里buff/cache的真实含义

free -h 输出中,很多新人看到used很大、available很小就慌了,其实 linux 的内存管理哲学是“闲着也是闲着”,会把空闲内存尽量用作 page cache 来加速文件读写。关键要看的是 available 字段,它才代表“在不触发swap的前提下还能分配多少内存”。

真正的内存杀手往往是应用自身。排查时我习惯配合 top 按内存排序(进入top后按大写m),或者用 ps aux --sort=-%mem | head -20 一次性列出内存占用前20的进程。如果发现某个java进程占了30g,那就不是内核缓存问题,而是应用侧jvm堆设置或内存泄漏,接下来要抓线程栈分析。

1.3 磁盘体检:df与df -i要一起看

df -h 大家都会用,但“磁盘满了”分两种情况:block满了和inode满了。inode是文件系统管理文件元数据的结构,当磁盘上小文件数量爆炸时,block没满但inode会被耗尽,表现就是报错“no space left on device”,可你查 df -h 却发现还有几十gb。

排查inode用 df -i ,定位大量小文件目录用 for i in /data/*; do echo $i; find $i | wc -l; done 这类组合命令。邮件队列、php会话目录、docker默认的json日志目录,都是inode耗尽的常客。处理时除了删除历史文件,还要注意程序本身是否在持续刷小文件,否则删完很快又会满。

2. 日志排查:从入门到找出真凶的实战链路

日志是linux运维最直接的破案线索,但海量日志不会自己把答案送到你面前。我这几年排查故障,百分之八十的时间花在日志过滤和上下文串联上,命令用来用去也就那几个,关键是组合思路。

2.1 journalctl与systemd日志时间轴

现在主流发行版都是systemd,服务日志优先用 journalctl -u 服务名 查看。日常必会参数:

journalctl -u nginx.service --since today
journalctl -u nginx.service --since "10 minutes ago" --until now
journalctl -u nginx.service -p err

-p err 表示只看error及以上级别,能快速过滤噪声。但要注意一点:journalctl默认显示的日志量是有限的,很多发行版重启后旧日志会丢。要持久化得修改 /etc/systemd/journald.conf 里的 storage=persistent ,否则机器一重启,排障现场直接“失忆”。

2.2 grep与awk的组合过滤技巧

大文件日志用 grep 是基本功,但有两点经验值得单独说。第一, grep 尽量加 --text -a ,避免日志文件被当成二进制文件导致匹配不到;第二,在管道里组合 awk 提取关键字段,比如从访问日志里按ip统计请求次数:

grep "2025-06-01" /var/log/nginx/access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head -20

这条命令的链路逻辑是:先按时间过滤,再取ip列,排序后去重统计,最后按次数倒序取前20。快速找出谁在刷接口、谁在爬站,非常管用。

2.3 tail与less的日志跟踪姿势

线上实时跟踪日志, tail -f 是最自然的操作。不过有几个增强技巧值得养成习惯:

tail -f /var/log/app.log

大写f比小写f强在“文件被轮转后自动重连”。很多应用日志每天切割,小写f在轮转后就停在旧文件上不动了,容易漏新日志。另外,日志文件比较多时,我喜欢用 less +f /var/log/xxx.log ,它既能像 tail -f 一样跟踪,又能按大写f停一下、然后shift+g跳到文件末尾查看历史内容,一个命令兼顾实时和回溯。

2.4 一次登录失败排查的完整串联

说个实际例子。某天客户反馈服务器偶尔登不上去,但过一会儿又正常。我先查了认证日志 /var/log/secure ,用 grep "failed" 捞出所有失败记录。结果发现失败集中在凌晨固定时段,来自同一个ip段。继续用 awk '{print $11}' 提取ip统计,确认是国外ip在暴力 破解。于是用 systemctl stop sshd 临时收紧,再配合fail2ban封禁该ip段,并修改sshd监听端口,问题当天就消停了。

从日志出发逐层下钻,是运维排查最可靠的方法 论。你不需要背特别偏的命令,把 grep awk sort uniq tail 这几个玩熟,大部分日志类问题都能啃下来。

3. 进程和资源拉扯:排查、定位与“手术”操作

服务器负载异常、内存被吃光、端口被占用,这些故障都绕不开进程操作。进程相关命令看着简单,但用好用准需要一点经验。

3.1 ps的组合排查姿势

ps aux 是最基础的信息源,但裸敲输出太杂。我常用的组合是:

ps -eo pid,ppid,%cpu,%mem,cmd --sort=-%cpu | head -20

-e 列出所有进程, -o 定制输出列, --sort=-%cpu 按cpu倒序,一眼看出谁在烧cpu。有些脚本进程在 top 里一闪而过不好抓,但 ps 高频执行几次就能锁定。

还有人习惯用 pgrep 快速找进程号,比如 pgrep -f java ,注意 -f 是匹配完整命令行,比只匹配进程名更准。配合 pstree 可以看进程的父子关系,排查“父进程挂了但子进程还在”的孤儿进程问题时很直观。

3.2 lsof:一切皆文件思想的落地

linux下“一切皆文件”, lsof 是这套哲学最实用的出口。我的两个高频使用场景:

反查端口被谁占用:

lsof -i:8080

这条输出会直接告诉你pid和进程名,比 netstat -tunlp 更直观,还多出命令路径列。

反查某个文件正被谁占用:

lsof | grep "deleted"

运维常见场景:磁盘空间显示明明删了文件, df -h 却一直没降。原因是有进程仍持有该文件的句柄。执行 lsof | grep deleted ,找到那个进程号,重启或kill它之后,空间才会真正释放。这个坑我单独会在第五节细说,因为真的太常见了。

3.3 kill的优雅与强制之别

kill 不只是杀进程,它靠信号工作。最常用的是:

kill -15 进程号   # sigterm,要求进程自行退出
kill -9 进程号    # sigkill,内核强制终结

我的习惯是,除非进程彻底卡死,否则先给sigterm,等几秒再决定是否升级到sigkill。为什么?sigterm允许进程做清理工作:释放临时文件、提交事务、关闭网络连接。数据库或消息队列这类进程直接 kill -9 ,很可能留下脏数据或未刷盘的写操作。

批量操作时,我常配合 pgrep 指定模式杀进程,例如:

pkill -9 -f "python3 /tmp/test.py"

pkill 一定要小心, -f 匹配整条命令行,难免误伤同名相似进程。杀之前建议先 pgrep -af 关键串 预览,确认没有其他关键进程被波及。

3.4 资源限制查看:ulimit不能只看默认值

很多线上应用莫名其妙被“杀”或者报“too many open files”,锅往往在 ulimit 。默认打开文件数经常是1024,对一个高并发服务来说远远不够。

ulimit -n

临时调大: ulimit -n 65535 ,但终端一关就失效。永久修改要看服务管理方式:如果是systemd服务,在 [service] 段写 limitnofile=65535 ;如果手动启动,改 /etc/security/limits.conf 。这个问题在排查tomcat、nginx高频连接时报错时几乎必现,提前把限制提上去能省很多事。

4. 网络问题别靠猜:这些诊断命令一试一个准

网络故障排障最忌讳“凭感觉”,一会儿觉得是防火墙,一会儿怀疑是dns。我习惯了按固定链路走:先确认本机网络状态,再看远端端口通不通,最后用真实请求验证。每一步都有对应命令,全程靠数据说话。

4.1 ss命令:比netstat更值得日常使用

netstat 是经典命令,但现在很多发行版默认没装。新项目我推荐直接用 ss ,参数风格接近,但输出更快更全。常用场景:

ss -lntp   # 查看所有监听的tcp端口和对应进程
ss -s      # 看一眼网络栈统计总览
ss -t state established | awk '{print $4}' | cut -d: -f1 | sort | uniq -c

第三条用于统计当前各本地ip上的连接数分布,多ip服务器做流量调度时很实用。排障时我最先看的是 ss -lntp ,确认服务确实监听在正确的ip和端口上,而不是自己以为的地址。

4.2 telnet与nc:探活远端口

很多公司安全策略严格,新环境我在 ss 上看到服务监听了,不代表外面能访问。远端探测的老祖宗是 telnet

telnet 192.168.1.100 3306

端口通,会看到mysql的版本欢迎信息;不通,则一直卡住直到超时。但telnet有个问题:它只能在交互模式下工作,不适合脚本化。写脚本探测我改用 nc (netcat):

nc -zv -w 3 192.168.1.100 3306

-z 表示只扫描不发送数据, -v 输出详情, -w 3 设置超时3秒。脚本里 根据返回码就能判断端口连通性。注意好多系统默认没装nc,得用 yum install nc apt install netcat-openbsd ,提前装好备用。

4.3 curl与ping的边界配合

很多人习惯先 ping 判断网络通不通,但请记住: ping 用的是icmp协议,很多云厂商或防火墙会屏蔽icmp,导致ping不通但业务完全正常。所以ping只能作为参考,最终判断还是依赖 curl 实际请求。

curl -i https://example.com
curl -v https://example.com/api/health --connect-timeout 5

-i 只拿响应头, -v 看完整握手过程,能定位是dns解析失败、tcp连接超时还是tls握手出错。还有一个细节: curl -v 里能看到 connected to ssl connection using 等阶段,如果卡在 “trying ip...” 说明tcp层不通,如果卡在 “ssl connection using”之后说明隧道建立了但应用响应慢。这些信息能直接缩小故障面。

4.4 路由与dns问题的定位

网络通但请求慢,除了看延迟,还要排查dns解析。 dig 是强力工具:

dig example.com +short

多执行几次,对比结果是否稳定。如果解析出的ip时对时错,可能是dns轮询或者本地缓存污染。路由层面的问题用 traceroute mtr

mtr -rwc 10 example.com

mtr在连续探测和统计丢包率方面比传统traceroute直观很多,每次排链路丢包,我这边的首选几乎都是它。

5. 文件与磁盘的隐性坑:删不掉、清不空、找不到

文件操作是linux入门最早的内容,但不少运行了多年的服务器,反而在文件管理上出幺蛾子。这一节专门讲三个高频又容易让人卡壳的场景。

5.1 删除文件后空间不释放的真正原因

现象:明明 rm -rf /data/app.log 删了日志文件, df -h 一看,磁盘使用率纹丝不动。新手会反复确认路径,老手会直接敲:

lsof | grep deleted

输出里会看到类似 java 1234 user /data/app.log (deleted) 的记录。意思是有进程一直持有这个已被删除文件的句柄,文件虽然从目录中移除了,但占用的磁盘块还没释放。解决方式有两种:一是重启持有该句柄的进程,二是 kill 进程号 强制结束。业务进程不方便重启的话,日志场景还有一个常规做法:用 cat /dev/null > /path/to/app.log 清空而不是删除,这样旧空间立即释放且进程不用重启。

5.2 查找大文件与碎文件目录的经典命令

磁盘快满时,最重要的是快速定位大文件。两个思路配合使用:

du -sh * | sort -rh | head -20
find / -xdev -type f -size +1g -exec ls -lh {} \;

du -sh * 在目录下直接按占用大小排序,适合从根目录逐层往下“剥洋葱”; find 配合 -size +1g 可以整个挂载点搜超过1g的大文件。注意 -xdev 防止搜到其他挂载点,否则会把 /proc /sys 这些虚拟文件系统也遍历一遍,耗时且无意义。

如果一个目录里有几十万个小文件, du 也会变慢,这时可以配合 find | wc -l 统计数量,优先清理那些按时间生成的临时目录。

5.3 rm -rf的防呆经验

rm -rf 是linux上最危险命令之一,但完全不用也不现实。我的几条防呆原则:

  • 使用绝对路径时必须逐字核对,特别是前后带有空格的路径。
  • 删除前先 ls 确认目标存在,再执行删除。
  • 关键目录建议先 tar 打包备份到其他机器,再动手。
  • 能用 find 定向删除的,不整目录 rm

另外,现在很多团队用回收站脚本或trash命令(如 trash-cli )来替代直接删除,把删除变成移动到临时目录并定期清理。对我来说,方案没有标准答案,能减少误操作风险的就是好方案。

6. 服务编排与自动化操作:systemctl到crontab的日常

前面聊的是排障手段,运维的另一半工作是确保服务稳定持续运行,该自启的自启,该定时执行的定时执行。这块的命令同样基础,但里面藏着的坑不少。

6.1 systemctl状态检查与自启动配置

管理服务现在基本统一用systemd。日常三连:

systemctl status nginx
systemctl enable --now nginx
systemctl restart nginx

enable --now 是“开机自启+立即启动”合并操作,在初始化部署时比分两步执行省事且避免遗漏。查看服务是否开机自启用 systemctl is-enabled nginx ,查看运行状态用 systemctl is-active nginx ,这两条适合写进脚本做健康检查。

如果服务没有原生systemd单元文件,自己写一个 /etc/systemd/system/xxx.service 也不难,关键段落是:

[unit]
description=my app
after=network.target

[service]
execstart=/opt/app/start.sh
restart=always
user=appuser

[install]
wantedby=multi-user.target

restart=always 是服务崩溃后自动拉起的关键。写完后记得 systemctl daemon-reload ,否则改了unit文件不会生效。这个坑我见过不止一次,排查半天发现服务配置改了,systemd还在用旧配置。

6.2 一个安全可靠的自启动脚本模板

很多应用不是原生的daemon进程,需要壳脚本启动。我习惯把自启动脚本写得“啰嗦”一点,把环境变量和日志路径都显式写全,避免cron或systemd启动时环境不一致:

#!/bin/bash
# 可执行脚本头部显式指定shebang,避免依赖登录shell环境
export java_home=/usr/local/jdk
export path=$java_home/bin:/usr/local/bin:/usr/bin:/bin
cd /opt/app && nohup java -jar app.jar > /var/log/app.log 2>&1 &
echo $! > /var/run/app.pid

脚本里把 java_home path 写死是我个人一直坚持的习惯。因为systemd或cron拉起脚本时,环境变量比登录终端少得多,少一个path导致java命令找不到的情况太常见了。

6.3 crontab的坑:环境变量与执行权限

定时任务也是运维高频操作。创建定时任务的姿势:

crontab -e   # 编辑当前用户的定时任务
crontab -l   # 查看当前用户的定时任务

不过crontab坑点非常多。第一是环境变量问题:cron执行时不会加载 /etc/profile ~/.bashrc ,你的脚本一旦依赖这些变量就会悄悄失败。我自己的处理方式是在脚本开头source环境文件,或者把必要变量写死在脚本里,正如上一节那样。

第二是执行权限问题:cron默认使用 /bin/sh 执行,有些发行版 sh 是dash而不是bash,bash专有语法(如 [[ ]] )会执行出错。稳妥的做法是在crontab里显式写成 */5 * * * * /bin/bash /opt/scripts/monitor.sh

第三是日志定位:cron任务失败往往没有报错。排查时我喜欢先在crontab里配置临时输出:

*/5 * * * * /opt/scripts/monitor.sh > /tmp/monitor.log 2>&1

跑一两个周期后看 /tmp/monitor.log ,基本能定位是脚本本身还是环境问题。确认无误后再把重定向去掉,避免日志撑爆 /tmp。

6.4 常用文件编辑与效率命令:vim和git的运维角色

很多纯运维向的新手容易忽略两个“非运维命令”: vim git 。但实际工作中,临时修改配置文件、回滚变更、对比不同版本差异,都离不开它们。

vim只要记住几个核心操作就够应付日常: i 进入插入模式,esc回到命令模式, :wq 保存退出, :q! 放弃修改, dd 删除一行, yy 复制一行, p 粘贴, /关键字 搜索。需要跨文件编辑时,最方便的是 :e 文件路径 以及 :vsp 分屏。

git在运维场景主要是“心里有底”——改配置前先 git init git add -a && git commit -m "backup before change" ,出问题直接 git diff 看改动,甚至 git checkout -- 文件 一键还原。我在生产服务器上管理 /etc 目录的全量配置也是用git仓库跟踪,虽然听着“重”,但每次排障时能立刻知道哪个配置文件被动过,这个能力远比背一堆花哨命令值钱。

回到开头说的那句:linux运维的命令不是背出来的,是“用出来的”。每一条看起来枯燥的命令,背后都对应着一次线上故障、一个凌晨三点爬起来处理的场景。把这十几个命令的用途、参数、坑点彻底吃透,再复杂的故障也能找到下手的第一个入口。下次再遇到服务器异常,不妨按这篇文章的排查顺序从头走一遍,你会发现自己慢慢就有了肌肉记忆。

以上就是linux运维排查必会命令整理:从cpu内存到日志网络的实战手册的详细内容,更多关于linux运维排查命令的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com