
1. 开篇——先搞清楚运维命令的学习路径很多刚接触Linux的朋友一上来就抱着《Linux命令大全》啃今天背一个tar明天背一个grep背了两周发现遇到问题还是无从下手。这个现象很常见问题不在记忆力而在学习路径上——运维命令不是用来背的是用来解决具体问题的。我接触Linux运维十来年带过不少新人也踩过不少坑。我的体会是基础运维命令的学习真正核心的不是会用某一条命令而是建立一套系统状态感知的能力。说白了就是你拿到一台陌生的Linux服务器能通过几条命令快速搞清楚这台机器是什么系统、跑了什么服务、资源吃紧在哪、日志里有没有异常。这个能力比记住一百条命令的语法都值钱。这篇文章我不打算给你罗列一份全部命令清单那种东西网上到处都是。我挑了一套日常运维真正高频使用的命令组合讲清楚每条命令解决什么问题、输出怎么解读、实测中常见哪些坑最后用两个真实故障案例串一遍排查思路。适读对象是刚接触Linux运维的同学以及那些已经会敲命令但遇到问题还是没头绪的朋友。开头先说明白文中所有命令我都在CentOS 7/8、Ubuntu 20.04/22.04上实测过Debian系和RedHat系的差异我会单独标注。命令参数以GNU coreutils版本为主部分涉及系统工具版本的差异我会顺带提一句。2. 系统信息采集——拿到一台陌生服务器先看什么2.1 操作系统与内核信息别急着装软件接手一台服务器我的习惯是先摸清底细。不是所有服务器都是你熟悉的发行版也不是所有内核版本都支持你想要的功能。这时候四类信息必看操作系统发行版、内核版本、主机架构、运行时长与负载。# 查看操作系统发行版信息RedHat系和Debian系通用 cat /etc/os-release # 查看内核版本与架构 uname -a # 单独看内核版本 uname -r # 单独看架构 uname -mcat /etc/os-release是最稳妥的一招几乎所有现代发行版都有这个文件。输出里的PRETTY_NAME会直接告诉你系统名称和版本号比如 CentOS Linux release 7.9.2009 (Core) 或 Ubuntu 22.04.3 LTS。知道了发行版后续用什么包管理器yum还是apt就确定了很多命令的细节差异也随之确定。uname -a输出内容比较多重点看三段内核版本比如3.10.0-1160.el7.x86_64、主机名hostname、架构x86_64还是aarch64。这里有个实操价值点确认架构之后再决定下载什么版本的软件包。我在ARM服务器上装过x86_64的二进制包装完跑不起来排查半天才发现是架构不匹配白白浪费一下午。接下来看运行时长和负载# 查看开机时长和系统负载uptime uptime # 查看内存使用情况 free -h # 查看磁盘使用情况 df -huptime输出的最后三个数字是1分钟、5分钟、15分钟的平均负载load average。很多人一看负载数字就慌其实要结合CPU核数来判断——单核机器负载到2确实偏高但16核机器负载到2根本不算事。判断负载是否正常的简单标准平均负载持续高于CPU核数说明系统可能过载了。free -h里的-h是人性化显示human-readable把字节换算成GB/MB。重点看两行Mem行的available列表示当前还有多少可用内存Swap行表示交换分区使用情况。注意free输出里的used列并不等于实际不可用内存因为Linux会把空闲内存用作缓存buff/cache这部分内存是可以在压力下释放的。所以判断内存是否够用看available比看used更准确。df -h查看各挂载点的磁盘占用情况。实际工作中我见过很多磁盘满了但df看不出来的案例——其实是文件被删除了但进程还占着文件句柄或者有隐藏的挂载点。这种情况光靠df不够要配合lsof排查这部分后面故障案例里详细讲。2.2 硬件资源画像——CPU、内存、磁盘的边界在哪里服务器卡顿的时候第一步不是重启而是要搞清楚资源瓶颈到底在哪里。我一般用三条命令给服务器做体检# 查看CPU信息核数、型号、频率 lscpu # 查看内存硬件信息 sudo dmidecode -t memory | head -50 # 查看磁盘IO情况 iostat -x 1 3lscpu是快速查看CPU信息的神器输出里直接给出CPU(s)逻辑核数、Model name型号、MHz主频等关键字段。注意区分Core(s) per socket和Thread(s) per core——两个参数相乘再乘以物理CPU颗数才是逻辑CPU总数。超线程开启时逻辑核数是物理核数的两倍判断负载是否过载时以逻辑核数为准。iostat命令需要安装sysstat包yum install sysstat或apt install sysstat。执行iostat -x 1 3的意思是每1秒采样一次共采样3次。重点关注%util列——这个值接近100%说明磁盘IO已经很紧张了。另一个关键指标是await表示IO请求的平均等待时间毫秒。机械硬盘的await正常应在20ms以下SSD通常在5ms以内。如果await很高但%util不高往往说明有IO排队或锁竞争未必是磁盘性能不足。有个经验供参考%util反映的是磁盘设备是否持续工作在满负荷状态但它并不能区分是读还是写造成的压力。如果想进一步定位看r/s每秒读次数和w/s每秒写次数配合pidstat -d能查到具体是哪个进程在大量读写磁盘。2.3 进程与端口——定位是谁在占用资源系统卡顿的另一个常见原因是有进程在偷跑。两条命令组合使用基本能锁住元凶# 动态查看进程状态按CPU或内存排序 top # 或者使用更直观的 htop需要安装 htop # 查看所有监听端口及其对应进程 ss -tlnp # 老系统用 netstat需要安装net-tools netstat -tlnptop进入交互界面后按P键按CPU使用率排序按M键按内存使用率排序这是两个最常用的快捷键。注意top默认显示的进程状态里有一个S列R表示运行中S表示睡眠Z表示僵尸进程D表示不可中断睡眠通常是等IO。看到大量D状态进程时系统多半在等磁盘IO这时候去看iostat准能找到问题了。ss -tlnp是查看端口监听状态的现代工具取代了老旧的netstat。参数解释-t只查看TCP-l只看监听状态-n不做域名反解加快速度、避免DNS超时-p显示对应的进程信息。输出里Local Address:Port列如果显示0.0.0.0:22表示监听在所有网卡的22端口如果显示127.0.0.1:3306表示只监听本机回环地址——这个差异在安全上意义很大前者意味着外部可访问后者只有本机才能连。排查端口被占用问题时ss -tlnp也是第一顺位的命令。关于ss -p需要说明一点非root用户执行时看不到进程名会显示users:((nginx,pid1234,fd8))这种信息但使用sudo后会显示完整的进程路径。所以在生产环境排查时习惯性地加上sudo。3. 文件与文本处理——日常操作高频的五个组合3.1 查找文件find、locate、which各司其职文件查找是运维日常最高频的操作之一但很多人习惯用一条命令走天下导致效率低下。我的分工习惯是找配置文件、日志文件的精确位置用which或whereis在已知目录下按条件查找用find全盘搜文件名不找内容用locate需要先updatedb构建索引。# 查找命令所在路径 which nginx # 查找命令及其相关文件二进制、源码、手册 whereis nginx # 在 /etc 下查找所有包含 nginx 的文件名 find /etc -name *nginx* # 查找最近24小时内修改过的文件 find /var/log -mtime -1 # 查找大于500MB的文件 find / -type f -size 500M # 定位可执行文件的位置基于PATH变量查找 which python3find的-mtime -1表示最近1天内修改过的文件-mtime 30表示30天以前修改过的文件。删除过期日志的时候这个用法特别有用先find /var/log -name *.log -mtime 30看看有哪些文件确认无误后再加-delete参数清理。locate查询速度飞快因为它查的是预建索引数据库。但有个坑新建的文件如果还没有执行updatedblocate是找不到的。所以在刚创建文件后不要立刻用locate找要么跑一次updatedb要么直接用find。另外locate在最小化安装的系统中未预装需要手动安装mlocate或plocate。我一直觉得find是那种参数看着多用熟了以后根本离不开的命令。再分享一个技巧find的-exec参数可以在查找结果上直接执行命令比如把所有.tmp文件批量删除find /tmp -name *.tmp -exec rm -f {} \;这里的{}是占位符代表每一个命中的文件\;表示命令结束。批量操作前建议先跑一遍不带-exec的find确认命中列表无误后再加执行参数。3.2 内容搜索grep的进阶使用不只是过滤关键词grep是运维命令中使用率排前三的工具但大多数人只用了它的皮毛——在文件里搜个关键词。实际工作中grep更强大的用法是作为流过滤器和别的命令组合成一条流水线。# 递归搜索目录下所有文件中的关键词显示行号 grep -rn error /var/log/nginx/ # 搜索时不区分大小写 grep -i warning /var/log/syslog # 显示匹配行的前后各3行上下文 grep -C 3 OutOfMemory /var/log/messages # 统计匹配行数 grep -c connection refused /var/log/nginx/access.log # 过滤进程信息 ps aux | grep java | grep -v grep最后一个组合值得展开说下ps aux | grep java会把你当前执行的grep命令本身也列出来因为它也包含了java这个关键词。加上grep -v grep就是把包含grep的行排除掉这样输出的都是真正的java进程。更严谨的做法是用pgrep -l java直接按进程名匹配输出更干净。grep -C参数context在排查日志时价值极大尤其是报错信息往往不是单独一条而是和上下文形成因果链条。比如看Java应用崩溃日志时OutOfMemory之前几行通常有堆栈信息后面的grep -C 5能帮你一次性抓到完整上下文不用来回翻文件。另一个实测中的常用技巧日志文件通常很大而且类Unix系统下日志还在持续写入。用tail配合grep实现实时过滤日志tail -f /var/log/nginx/access.log | grep 404这样终端里只输出新写入日志中包含404的行在排查线上问题时非常高效。不过注意管道符会缓冲输出如果希望立即看到结果可以加--line-buffered参数强制行缓冲。3.3 文本查看与编辑head、tail、sed的配合日志排查是文本命令使用最密集的场景。我的日志查看三件套# 查看文件开头30行 head -n 30 /var/log/messages # 实时跟踪文件变化查看最新写入的日志 tail -f /var/log/nginx/error.log # 查看文件末尾50行且文件增长时自动刷新 tail -n 50 -f /var/log/app.log # 用sed直接打印指定行范围比如100到120行 sed -n 100,120p /var/log/app.logtail -f是运维调试时最依赖的命令之一。注意区别-f和-F-f跟踪的是文件描述符如果日志文件被轮转logrotate把旧日志改名、新建文件-f会跟丢-F根据文件名重新跟踪轮转后能自动续上。所以生产环境我习惯用tail -F避免日志轮转后显示中断。sed -n 100,120p这种用法适合定位大文件中的某个区间。比如你通过grep -n找到了报错在第1500行就可以用sed -n 1490,1520p把附近的内容打印出来看上下文。sed的流编辑能力在批量替换场景中也很常用但涉及文件修改时务必注意备份。我最常用的替换命令格式# 把nginx.conf中所有 www.old-domain.com 替换为 www.new-domain.com sed -i s/www\.old-domain\.com/www.new-domain.com/g /etc/nginx/nginx.conf-i表示原地修改字符里的\.是转义因为.在正则里是任意字符。g表示替换每一行中的所有匹配项而不是只替换第一个。执行替换前建议先去掉-i参数跑一遍确认输出符合预期再加-i真正写文件。3.4 打包压缩与传输tar与rsync的取舍文件传输和备份是每个运维都会遇到的问题。tar负责打包压缩rsync负责增量同步两者各有适用场景。# 打包并压缩-z 表示gzip压缩-c 创建-v 显示过程-f 指定文件名 tar -zcvf backup.tar.gz /var/www/html/ # 解压到指定目录 tar -zxvf backup.tar.gz -C /tmp/restore/ # 排除某个子目录 tar -zcvf backup.tar.gz /var/www/html/ --exclude/var/www/html/cache # 只查看压缩包内容不解压 tar -ztvf backup.tar.gz | head -20 # rsync差异化同步到远程服务器-a 归档模式-v 显示-z 压缩传输 rsync -avz /var/www/html/ userbackup-server:/backup/www/tar的参数顺序比较讲究。GNU tar的习惯是参数可以合并写-zcvf和-czvf等价但-f后面必须紧跟文件名因为它表示哪个参数是文件参数。解压时务必养成为解压内容先建个临时目录的习惯避免压缩包内文件路径直接把当前目录搞乱。rsync的核心价值在于增量同步——第一次全量传输后后续同步只传变化过的文件块。这个特性让它在备份远程服务器数据时比scp高效得多。实测中我要提两个参数--delete表示远端删除本地已删除的文件保持两端完全一致但要小心误删--progress显示传输进度大文件传输时很有必要。rsync还有一个很实用的场景在本机不同目录之间同步不需要网络。比如发布代码前后用 rsync 把某个目录的内容增量同步到另一个目录比cp更节省时间和磁盘IO。3.5 权限管理别让权限问题成为安全隐患Linux权限模型r/w/x看似简单但实际操作中经常踩坑。我认为有三个点最值得反复强调。第一chown修改归属时注意使用-R参数的场景范围。修改目录下所有文件的属主使用# 递归修改目录属主为 www 用户、www 组 chown -R www:www /var/www/html/不加-R只改目录本身文件不变。很多应用部署后出现没权限写日志的问题就是只改了目录权限、没改里面文件的属主。第二chmod的数字模式要理解其含义。chmod 755中的每一位分别是属主、属组、其他人的权限。7421读写执行541读执行。网站目录常用755配置文件常用644。给可执行脚本加执行权限chmod x deploy.sh第三SUID/SGID/Sticky Bit的实战意义。目录上设置了Sticky Bit表现为drwxrwxrwt表示只有文件属主能删除自己的文件/tmp目录就是典型例子。SUID作用于可执行文件使执行者临时获得属主权限/usr/bin/passwd就是SUID文件。这些特殊权限位在排查为什么我能删除别人的文件或为什么这个程序能读root才能读的文件时往往是关键答案。权限相关的故障我用一个原则指导能不用root运行的服务绝不用root运行。很多安全漏洞都是因为进程以过高权限运行而被利用的。4. 网络排查五板斧——连接不上时按这个顺序查4.1 ping与traceroute先判断网络通不通排查网络问题我的固定顺序是从底层往上层先确认本机IP和网关是否正确ip addr/ip route再确认目标主机通不通ping不通时用traceroute定位断在哪一跳通的话再查端口telnet/nc。# 查看网卡IP地址和状态 ip addr show # 查看默认路由 ip route show # 测试连通性持续pingCtrlC停止 ping -c 5 8.8.8.8 # 查看数据包到达目标经过了哪些路由节点 traceroute -n -T 8.8.8.8 -p 80ping -c 5表示发送5个ICMP包后自动停止避免手工CtrlC。traceroute -n不做域名反解输出更快也更干净。-T -p 80表示用TCP SYN方式探测80端口这在防火墙禁ICMP的环境中非常有用——很多云环境默认禁ping但TCP探测能正常工作。一个常见误解ping不通等于网络不通不一定。很多云主机的安全组默认丢弃ICMP包但它们之间的TCP连接完全正常。反过来ping通但业务连接失败问题就聚焦在端口、防火墙或服务本身。所以不要把所有判断压在ping上。4.2 端口连通性测试telnet还是nc确认端口是否可达两条命令各有千秋# telnet测试端口兼容性最好很多系统预装 telnet 192.168.1.10 3306 # nc测试端口功能更强支持TCP/UDP nc -vz 192.168.1.10 3306telnet连接成功会显示Connected to失败则提示Connection refused或timed out。Connection refused说明目标主机可达但端口上没有服务监听timed out说明网络层不可达或被防火墙丢弃。这两个错误信息的区分是排查网络问题的关键线索。nc -vz中的-v显示详细过程-z表示不发送数据、只探测端口。它比telnet更好的地方在于支持批量扫描多个端口# 一次性测试多个端口 nc -vz 192.168.1.10 22 80 443 3306我在排查应用连不上数据库的报障时习惯先nc -vz测试应用服务器到数据库服务器的3306端口。如果通问题在应用配置或数据库授权如果不通再看云安全组、防火墙和数据库监听地址。这个定位思路能把问题域缩小一半。4.3 抓包工具tcpdump——终极定位手段当nc、telnet都无法解释问题时抓包是最后的实锤手段。tcpdump是Linux下最常用的命令行抓包工具。# 抓取指定网卡上到目标IP的80端口流量 sudo tcpdump -i eth0 host 192.168.1.100 and port 80 # 抓包后保存到文件供后续分析 sudo tcpdump -i eth0 -w /tmp/capture.pcap host 192.168.1.100 # 读取pcap文件 sudo tcpdump -r /tmp/capture.pcap # 只看TCP三次握手包 sudo tcpdump -i eth0 tcp[tcpflags] (tcp-syn|tcp-ack) ! 0 -c 20-i指定网卡-w保存文件-c指定抓取包数量后自动停止。在实际排障中我常用这个组合sudo tcpdump -i any port 8080 -nn-nn不做端口名和主机名解析输出更清晰。抓包输出里能看到SYN包发出、SYN-ACK包返回、ACK包确认的三次握手过程——如果只有SYN没有SYN-ACK说明对端没有响应或防火墙丢弃了如果SYN-ACK返回了但握手没完成问题可能在本地防火墙或路由。抓包是有一定的学习曲线但整个排查过程中它给的信息量是其他工具无法替代的。我见过不少服务起不来但日志没报错的现场最后靠tcpdump发现是TCP连接被对端RST复位——真相在日志之外。4.4 DNS和本地解析连得上IP但连不上域名一个很常见的症状我能ping通IP但访问域名超时。这种场景90%问题出在DNS解析。常用排查命令# 查询域名解析的DNS记录 nslookup example.com # 更详细地指定DNS服务器查询 nslookup example.com 8.8.8.8 # 测试解析耗时 dig example.com # 查看系统当前DNS配置 cat /etc/resolv.conf # 查看本机域名解析缓存 # 传统方式没有缓存命令systemd-resolved可用 systemd-resolve --statisticscat /etc/resolv.conf是第一步我见过配置里的nameserver指向一个已停用的内网DNS导致大面积解析失败。dig输出中的Query time能看出解析耗时如果耗时很高说明DNS服务器响应慢或网络路径不佳。还有一类问题修改了/etc/hosts但访问域名没变这是因为有些服务如Nginx在启动时就读hosts缓存了修改后需重启服务。另外Nginx的resolver配置、Java应用的JVM DNS缓存、系统nscd服务都可能产生多层缓存排查时都要意识得到。4.5 防火墙排查firewalld与iptables的日常操作防火墙规则的坑防不胜防。自认为端口已开放但外部连接始终失败好不容易放行了端口过段时间又神秘堵塞——这些都是运维日常。# 查看当前防火墙规则 sudo firewall-cmd --list-all # 永久添加端口需reload生效 sudo firewall-cmd --permanent --add-port8080/tcp sudo firewall-cmd --reload # iptables 查看规则 sudo iptables -L -n --line-numbers如果使用的云平台有安全组功能服务器内部还有firewalld那端口可达性取决于两者的交集——两边都要放行。排查时必须两层一起看不能只看了一层就下结论。iptables规则里常见的坑是规则顺序iptables按顺序匹配先匹配到的规则先生效。如果前面有一条REJECT all规则后面再加放行规则也没用。用--line-numbers查看规则序号iptables -D INPUT 5删除第5条规则这是调整规则顺序的常用操作。5. 日志与系统状态——把隐形故障揪出来5.1 日志目录结构不同发行版的日志都在哪排障时最怕的其实不是日志内容看不懂而是找不到日志在哪。不同发行版的日志目录有差异我用一张表给你理清系统/服务日志路径说明CentOS 6及以前/var/log/messages系统总日志CentOS 7/8、 Ubuntu 18.04/var/log/syslog系统总日志Debian系认证日志/var/log/secureRedHat系、/var/log/auth.logDebian系登录认证记录内核日志/var/log/kern.logDebian系内核输出Nginx/var/log/nginx/access.log、error.logWeb访问与错误MySQL/MariaDB/var/log/mysql/error.log数据库错误日志还有个重要的排查入口是dmesg内核环形缓冲区消息很多硬件级别的问题只在dmesg里体现比如磁盘IO错误、内存ECC校验、网卡LINK状态变化等# 查看内核环形缓冲区最近的消息 dmesg | tail -50 # 实时跟踪内核消息 dmesg -w我排查过一台偶尔丢包的服务器看ping时通时不通查dmesg发现网卡在反复Link is down/up最后定位是网线接触不良。这种问题在业务日志里完全看不到只有内核日志会记录。5.2 journalctlsystemd时代日志查询的正确姿势现在的Linux发行版基本都使用systemd管理服务日志系统也从分散的文本文件转向了集中管理的journald。journalctl是查询这些日志的核心工具。# 查看本次启动以来的所有日志 journalctl -b # 查看指定服务的日志 journalctl -u nginx.service # 查看最近30分钟的服务日志 journalctl -u nginx.service --since 30 minutes ago # 跟踪指定服务的日志变化 journalctl -u nginx.service -f # 按错误级别筛选0 emerg ~ 7 debug journalctl -p err -b-b参数表示本次启动boot排障时非常有用——重启前的旧日志不会干扰视线。-u指定服务单元名。-f是--follow的简写类似tail -f持续跟踪日志输出。这些参数可以组合使用比如journalctl -u mysql -p err --since 1 hour ago只看最近一小时MySQL的错误日志。journalctl的日志默认是持久化的吗不一定。如果/var/log/journal目录存在日志会在重启后保留如果只存在/run/log/journal重启即清日志不会持久化。生产环境建议启用持久化# 创建持久化日志目录并重启日志服务 sudo mkdir -p /var/log/journal sudo systemctl restart systemd-journald这个配置我建议在新服务器初始化时直接做掉否则等你想查三天前发生了什么的时候日志可能已经清了。5.3 定位CPU和内存的隐形杀手top与ps的深度组合刚才提到的top只是第一步筛选要精确定位问题进程还需要几个组合命令。# 按CPU使用率排序查看所有进程top的批处理模式 top -bn1 | head -30 # 查看指定进程的线程级别CPU占用常用于Java应用 top -H -p PID # 查看进程打开的文件句柄数排查too many open files ls /proc/PID/fd | wc -l # 查看进程的工作目录 lsof -p PID | grep cwdJava应用排查CPU飙高时top -H -p能看到线程级别的CPU占用结合jstack把线程栈dump出来就能定位到具体代码行。这个技能在线上Java服务CPU跑满的场景下几乎是必用套路。文件句柄数是个容易忽略的指标。Nginx报too many open files或者应用抛SocketException: Too many open files根源经常是两个一个是进程的ulimit软限制太低另一个是程序确实存在文件句柄泄漏。排查方法上面给了用/proc/PID/fd数句柄如果是泄漏配合lsof -p PID看大量打开的句柄集中在哪个文件/哪个socket就能猜出哪块逻辑出了问题。5.4 查看历史负载用sar还原事故发生现场遇到系统今天凌晨卡了一下但当时没人盯着的情况sar是最值得信赖的事后取证工具。# 查看历史CPU使用率数据从系统启动后自动采集 sar -u -f /var/log/sa/sa$(date %d) # 查看历史内存使用率 sar -r -f /var/log/sa/sa$(date %d) # 查看历史磁盘IO情况 sar -b -f /var/log/sa/sa$(date %d)sar是sysstat包的一部分它通过定时任务/etc/cron.d/sysstat定期采集系统状态到/var/log/sa/目录。所以必须保证sysstat服务和对应的cron任务启用了否则没有历史数据可查。这个工具的存在让事故复盘从靠猜变成了靠数据。我用sar还原过一起深夜的MySQL慢查询事件事后查看当天23:00-23:10的CPU和负载数据发现这个时间点CPU飙升、IO等待偏高结合MySQL慢查询日志定位到一条半夜批处理产生的全表扫描SQL。没有sar这类问题基本只能下次复现再抓。6. 两个真实故障排查案例——把命令串成思路6.1 案例一磁盘明明没满服务却报No space left on device现象某应用服务器忽然报错提示No space left on device但我执行df -h查看磁盘所有挂载点的使用率都不超过60%。第一反应不是怀疑df的输出而是想还有什么情况会导致空间满排查链路# 第一步确认inode是否耗尽df只看的是数据块inode是文件索引节点 df -i一查发现/分区的IUse%显示100%。Linux上创建每个文件都需要一个inodeinode耗尽后即使磁盘有剩余空间也无法新建文件。问题根源往往是某个目录下堆积了大量的小文件比如程序异常产生的临时文件、未清理的缓存文件。继续定位是哪个目录出了问题# 统计每个子目录的文件数量定位文件堆积点 find / -xdev -type f | awk -F/ {print $2} | sort | uniq -c | sort -rn | head最终查出一个运行中的Java应用在/tmp下持续产生大量临时文件且异常退出时没有清理。旧进程又未释放已删除文件的磁盘块删除文件后占用文件句柄的进程不退出空间也不会释放用lsof | grep deleted抓出这些已删除但被占用的文件确认后重启相关进程磁盘占用立刻降下来了。处理要点inode问题的常规优化手段是清理小文件、设置crond定期清理临时目录、为容易堆积小文件的目录使用支持更高inode的文件系统如xfs但最根本的是让应用正常释放资源。6.2 案例二端口正常应用却连不上数据库现象应用日志里出现连接数据库超时但我在数据库服务器上执行ss -tlnp确认3306端口正常监听本机测试也能正常连接。排查链路# 第一步从应用服务器测试到数据库的3306端口 nc -vz 192.168.1.10 3306输出显示Connection timed out。既然是timed out说明不是端口没有服务的问题而是网络路径上被拦截了。接着在本机抓包确认sudo tcpdump -i eth0 port 3306 -nn看到应用服务器的SYN包持续发出但没有任何SYN-ACK回应。用traceroute -n -T 192.168.1.10 -p 3306检查网络路径发现数据包在某个中间IP后就丢失了最后定位是云安全组的访问控制只放行了该数据库的同VPC网段来源而应用服务器新调整了网段导致不在放行范围内。这类问题的排查顺序值得反复练习先分清是端口关闭Connection refused还是路径不通timeout前者关注服务和监听地址后者关注防火墙、安全组和路由。一次定位的准确率会随着经验快速提升。7. 命令学习的效率之道——先建场景清单再建命令清单最后聊几句学习方法。我刚入行的时候也走过背命令大全的弯路真正让命令融会贯通的转折点是建立场景-命令的映射关系而不是命令-语法的死记硬背。我建议你按下面这张运维场景-核心命令清单来梳理自己的知识树贴在工位上场景核心命令组合关键输出/指标新服务器摸底cat /etc/os-release、lscpu、free -h、df -h发行版、核数、内存、磁盘系统卡顿排查top、iostat -x、free -h高CPU进程、%util、available端口不通ss -tlnp、nc -vz、traceroute监听状态、Connection refused/timeout日志异常tail -F、journalctl -u、grep -C报错上下文、服务近期日志磁盘空间满df -h、df -i、lsof | grep deletedinode占用、已删除未释放文件文件查找find、which、locate路径、最近修改、大小过滤备份迁移tar、rsync压缩进度、增量传输差异每个场景下主用命令通常就两三条剩下的参数是按需查询而不是背下来的。用man或tldr一个提供精简命令说明的工具随时查即可真正重要的是能在脑子里快速映射成问题-工具-结论的分析路径。另外建议实操时开个虚拟机多折腾刻意给自己制造故障比如故意把防火墙规则写错、故意创建一个无法删除的目录在非空且没有写权限的目录下、故意把文件属主改成乱码然后自己一步步排查解决。这些刻意练习比刷一百篇教程都管用——排查经验本质上是在错误中积累的。我把这套思路浓缩成一句话基础运维命令不是终点而是建立系统心态的工具。每敲一条命令想三件事——它解决了什么问题、输出说明了什么、如果输出不符合预期下一步查什么。做到这三点你离一个能独立扛事儿的运维就不远了。