多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

运维常用命令实战指南:从服务器体检到故障排查全场景解析

运维常用命令实战指南:从服务器体检到故障排查全场景解析 做运维这些年最常被问到的一句话就是运维常用命令到底该掌握哪些每次听到这个问题我都想起自己刚入行时抱着Linux命令大全背单词的日子后来才明白命令背得再多真到故障现场想不起来该用哪一条等于白学。这篇文章我想换个方式聊命令不讲零散的语法而是按真实排查场景把最常用的命令串起来——接手新服务器怎么看家底、CPU和内存告警怎么定位、磁盘和日志为什么总是同时爆、容器和K8s环境下的命令习惯怎么变、网络不通从哪一层开始查最后再聊聊怎么把这些命令整理成自己能快速检索的手册。无论你是刚入行的运维新人还是写脚本写到麻的桌面运维、网工这篇都应该能给你一些参考。1. 接手陌生服务器先花十分钟摸清家底很多运维同学接手一套老系统时第一反应是去看文档、翻交接记录。但真实环境里文档经常是过期的拓扑图永远是上个版本的最靠谱的做法其实是直接登录服务器用命令把现状摸一遍。这套操作我做了无数次十分钟内能搞清楚五件事系统是什么版本、硬件配置多少、跑了哪些服务、开了哪些端口、资源占用什么水平。1.1 系统版本与硬件配置先搞清楚你面对的是什么登录服务器第一步我习惯先跑一组信息收集命令按顺序来uname -a cat /etc/os-release lscpu free -h lsblk df -huname -a看内核版本/etc/os-release看发行版名称和版本号。这两条决定了你后续装软件、配源、打补丁的方式CentOS 7和Ubuntu 22.04的命令习惯差别很大别用错。lscpu看CPU型号、核数、是否开启超线程free -h看内存总量和当前使用lsblk看磁盘分区结构df -h看文件系统挂载和空间使用。这一套下来这套服务器的“体检报告”基本就有了。我见过不少新人上来就top看半天不知道load average是什么意思就是因为没先确认CPU核数。load average的三个数值是1分钟、5分钟、15分钟的平均负载判断是否过载不能只看绝对值要看它和CPU核数的比例。4核机器负载长期在4以上已经算繁忙了64核机器负载20都很正常。1.2 运行中的服务和监听端口别等告警了才想起来查摸完硬件下一步是看这台机器在跑什么。我的固定命令是systemctl list-units --typeservice --staterunning ss -lntp ps aux --sort-%mem | head -20systemctl list-units列出所有正在运行的systemd服务能快速看到MySQL、Nginx、Redis这些组件是不是活着。ss -lntp查看当前监听端口和对应进程这里注意现在的系统基本用ss替代netstat了ss输出更快、信息更全-l只看监听、-n不做域名解析、-t只看TCP、-p显示进程名。ps aux --sort-%mem按内存占用排序看进程前二十个基本能反映这台机器的业务负载分布。端口这块有个经验之谈如果ss输出里看到一个端口同时被多个进程监听或者监听地址不是预期IP大概率是服务配置有问题或者有异常进程。配合lsof -i:端口号可以精确确认某个端口对应的PID比如lsof -i:3306看MySQL是否正常监听。1.3 把重复操作固化成脚本省下的是以后每次排查的时间摸家底这件事每个运维几乎天天做所以我强烈建议把这组命令写成一个脚本放到/usr/local/bin/sysinfo.sh比如把系统信息、CPU、内存、磁盘、服务、端口都打印出来。下面这个是我自己常用的精简版#!/bin/bash echo 系统信息 uname -a cat /etc/os-release | grep PRETTY_NAME echo CPU lscpu | grep -E Model name|^CPU\(s\) echo 内存 free -h echo 磁盘 df -h | grep -v tmpfs echo 监听端口 ss -lntp echo 内存占用TOP10 ps aux --sort-%mem | head -10 echo CPU占用TOP10 ps aux --sort-%cpu | head -10脚本的优势不只是省打字而是建立一种稳定的检查基线。输出格式固定之后你对比“今天”和“上周”的输出更容易发现异常看到的内存占用TOP10里突然多出一个陌生进程下一步就知道该怎么挖了。这个脚本我建议放在Git仓库里管理换机器、换公司都能直接拉下来用。2. 性能告警排查从“机器很忙”到“知道谁在忙”监控告警弹出来说CPU使用率95%或者内存使用率持续高位这时候最忌讳的就是盲目操作。我的习惯是先不要急着重启服务花两分钟确认负载到底是谁产生的。这一节我把CPU、内存、磁盘IO三条线的排查命令拆开讲每一类都给你一条能落地的排查路径。2.1 学会读top第一屏比记住几十个参数更值钱top是最常用的性能命令但很多人的使用方式就是打开看一眼就关掉。top第一屏的信息密度很高第一行load average我前面说过要结合CPU核数判断第二行Tasks里的running数量如果长期大于核数说明调度排队严重第三行%Cpu(s)里us表示用户态占用sy表示内核态占用wa代表I/O等待wa高通常意味着磁盘是瓶颈。进入top交互界面后按1展开每个CPU核心的使用率按P按CPU排序按M按内存排序按c显示完整命令行。这些交互键比记忆一堆参数更实用。我在排查的时候通常会几条top -bn1间隔几秒采样几次动态观察而不是只看一秒钟的快照。比如连续三次采样的CPU占用从30%一路涨到90%和一开始就90%但保持稳定处理思路完全不同——前者要抓增长源头后者要看配置是否需要扩容。2.2 CPU排查三件套mpstat、pidstat、top -H如果确认CPU跑高我一般用一组命令组合定位到具体线程mpstat -P ALL 1 pidstat -p ALL 1 top -H -p 进程PIDmpstat -P ALL 1可以每秒刷新一次并显示每个CPU核心的使用率。如果只有某一个核跑满而其他核很空闲多半是单线程应用或者中断绑定问题如果所有核都跑满那是整体并发上来了。pidstat -p ALL 1会打印每个进程的CPU占用率比top更适合做数据采样方便把输出重定向到文件里做趋势分析。top -H -p PID是查看某个进程内部线程的CPU占用对排查Java应用特别有用。我曾经遇到一个Java服务CPU飙高用这个命令看到某个线程占用300%多拿到线程号转十六进制再用jstack PID | grep -A 30 十六进制线程号直接定位到是GC线程在疯狂回收最后发现是堆内存配置太小。命令行排查到这个深度基本就能给开发提供一个明确方向了。2.3 内存排查别把buff/cache当成业务占用内存告警是最容易误判的告警之一。不少新手看到free -h里used很高就慌了实际上Linux的内存策略是“闲着也是闲着”会把多余内存用作buff/cache来提升磁盘访问性能这部分内存在业务需要时是可以释放的。所以重点要看的是available这一列它表示“在不触发交换的情况下可供新进程使用的内存估算值”。再往下排查我会看vmstat 1的si、so两列如果持续大于0说明系统正在做内存交换物理内存是真的不够用了这时候加内存或者优化应用内存占用才是正路。排查谁在吃内存用ps aux --sort-%mem查进程级别查得更细可以装smem它能看到按实际物理内存排序的结果准确区分共享内存的重复计算问题。如果是内核触发OOM Kill一定记得查一下dmesg -T | grep -i -E out of memory|oom journalctl -k --since 1 hour ago | grep -i oomOOM日志里会明确记录是哪个进程触发了当时内存占用多少这对复盘故障至关重要。我踩过的一个坑是只盯着MySQL的OOM日志结果发现真正被Kill的是一个内存泄漏的Java进程MySQL只是被连坐。所以设计监控告警时一定要把系统级OOM事件单独拉出来别混在业务日志里。2.4 磁盘IO排查iostat和iotop怎么配合使用磁盘IO问题最常见的现象是应用响应变慢、CPU的wa值升高、数据库慢查询增多。排查命令我有三件套iostat -x 1 iostat -x 1 3 /tmp/io_analysis.txt iotop -oiostat -x 1重点看%util、await、svctm这几列。%util接近100%表示磁盘设备已经满负荷运转await表示I/O请求的平均等待时间如果很高说明请求排队严重。做一个简单对比试验你会发现同一块SSD的await在1ms左右机械硬盘可能到十几毫秒云硬盘的跨区域挂载盘还会出现更夸张的波动。iotop -o只显示正在做I/O的进程适合定位是哪个进程在疯狂写盘。一次生产事故排查中我通过iostat确认磁盘util接近100%再用iotop定位到是日志收集Agent在不停地扫描文件最后调整了它的采集频率就解决了。记住一个原则性能排查一定要“先现象、再定位、后动作”别看到IO高就重启数据库方向错了只会让故障更严重。3. 磁盘和日志双杀两次差点背锅的救场经历磁盘告警和日志爆满几乎每个运维都遇到过。这两个问题往往同时发生——日志文件把磁盘写满了磁盘满了服务就写不了日志形成恶性循环。我把两次亲身经历的排查过程写出来不是为了讲故事而是这些排查链路大概率会在你的工作中重演。3.1 df和du数据对不上八成是有deleted文件被进程占用一次典型的场景监控报/根分区使用率95%我登录上去执行df -h确实满了。但跑到各个目录下用du -sh *统计加起来怎么都不够df显示的占用最后差了近40G。如果你也遇到这种情况不要怀疑命令算错了大概率是有文件被删除了但仍有进程持有它的句柄文件占用的磁盘空间没有真正释放。这时的定位命令是lsof | grep deletedlsof | grep deleted会列出所有已被删除但仍被进程打开的文件。找到占用大文件的那个进程后确认它是哪个服务的然后决定是重启服务释放句柄还是让进程停止写入后手动清理。那次我定位到是一个日志轮转脚本误删了正在被Java进程写入的日志文件由于Java进程一直没重启空间就一直没有吐出来。处理办法就是重启Java应用磁盘使用率瞬间回落。这里我想多说一句很多线上故障都是“好心办坏事”造成的。看到磁盘快满了第一反应是删日志文件但如果这个文件正在被进程写入用rm删掉反而容易出现空间不释放、进程继续写隐形句柄的问题。更安全的做法是先看进程情况、再决定是清空文件还是重启服务。清空大文件我一般用 /path/to/file.log而不是rm这样既能立刻释放空间又不会让文件句柄失效。3.2 journald日志无限膨胀journalctl是你的清理入口使用systemd的系统默认会把服务日志收集到journald里。很多运维习惯了看/var/log/messages或应用自己的日志文件往往会忽略journald等到发现的时候/var/log/journal目录已经占了几十G。先查占用再清理journalctl --disk-usage journalctl --vacuum-size500M journalctl --vacuum-time7d--disk-usage查看journal日志总大小--vacuum-size500M会把日志压缩清理到500M以内--vacuum-time7d只保留最近7天日志。我的建议是不要只做一次清理而是修改journald的持久化配置。编辑/etc/systemd/journald.conf设置SystemMaxUse1G然后重启systemd-journald服务这样日志大小会被严格限制在1G以内以后不用再三天两头手动清。顺带提醒清理日志前先确认是否有人需要做日志审计或排障。有一次我清理了半年前的journal日志正好赶上安全团队要回溯某个时间段的登录记录虽然日志还在但查起来很费劲。运维的任何清理动作都要有记录、有预期不能图一时痛快。3.3 logrotate配置得好日志才能“自生自灭”日志管理的治本方案是配置logrotate轮转而不是等磁盘满了再手动清。系统的一些核心日志默认已经配好了轮转策略在/etc/logrotate.d/目录下能看到对应服务的配置。但业务应用日志经常没有默认配置需要自己补上这是我这里给一个通用模板/var/log/myapp/*.log { daily rotate 14 compress delaycompress missingok notifempty copytruncate }这个配置的意思是每天轮转一次保留14份历史日志旧日志用gzip压缩如果当天没有日志也不报错。copytruncate是我在业务日志上特别推荐的参数——它先复制日志文件内容再清空原文件应用进程不需要重开文件句柄对正在写入的Java、Python进程非常友好。如果不加的话每次轮转都要靠create 644新建文件有些应用不会自动重新打开文件日志就写到旧句柄里去了。配置完成后可以用logrotate -f /etc/logrotate.d/myapp强制触发一次轮转确认没有报错。之后再定期检查/var/lib/logrotate/status文件看最近轮转执行情况。3.4 大文件定位三板斧别再一个个目录翻查磁盘空间占用时我常用的三个命令是find / -xdev -type f -size 1G -exec ls -lh {} \; du -sh /var/log/* /opt/* /home/* 2/dev/null | sort -rh | head -20 ncdu /find全盘扫描大于1G的文件-xdev参数让它不要跨文件系统扫描避免把/proc、/sys这种虚拟目录也扫进去导致输出爆炸。du -sh配合sort看各目录的占用排行。ncdu是交互式磁盘分析工具在终端里可以直接看到大文件和目录占比遇到一个动不动几十G的目录用它能很快判断哪些子目录是大头。这三个配合市面上那些“网络运维工具箱”“桌面运维助手”类工具各自都有适用场景但命令行这几招是最高效的兜底方案。4. 容器和编排环境来了命令习惯必须升级早几年运维是直接连服务器操作进程和数据现在越来越多的服务跑在Docker容器里再往上是Kubernetes集群。环境变了常用命令的重心也在变。手上同时管着几十台虚机和成百上千个Pod靠以前ps、kill那套已经不够用了这一节我把自己高频使用的容器命令清单和排障思路整理出来。4.1 Docker日常操作最常用的核心命令其实就十个以内Docker命令看着多日常运维真正高频的集中在以下这些docker ps -a docker logs --tail200 -f 容器名 docker exec -it 容器名 bash docker stats --no-stream docker inspect 容器名 docker top 容器名 docker restart 容器名 docker stop 容器名 docker rm 容器名docker ps -a不仅要看运行中的容器还要看Exited状态的容器——排障时第一个要确认的就是容器是否还活着。docker logs --tail200 -f是拉日志的常规操作-f保持跟踪。docker exec -it进入容器内部很多人习惯直接进容器用bash但要提醒一下容器里不一定有bash有些精简镜像只有sh所以docker exec -it 容器名 sh通常更通用。docker inspect是我排查容器异常时最常看的命令它返回一段JSON里面包含了容器的完整配置和状态。重点看State字段下的Status、ExitCode、OOMKilled比如ExitCode是137表示被SIGKILL杀死大概率是内存超限OOMKilled为true说明触发了容器内存限制。docker top可以查容器内进程在宿主机上对应的PID这在排查“哪个容器在抢CPU”时非常有用。4.2 一次容器不断重启的完整排查链路我拿一个真实场景走一遍完整排查链路。某个应用容器被监控告警提示不断Restarting页面访问时好时坏。我登到宿主机第一步docker ps -a看到容器状态是RestartingRestartCount一直往上加。第二步docker logs --tail100 容器名发现应用启动时报数据库连接拒绝但数据库容器单独看是正常的。第三步docker inspect 容器名查看网络配置发现容器使用的网络模式是bridge而数据库容器在另一个自定义网络里两个容器互相ping不通。问题定位到是创建容器时网络没指定对。处理方式很简单把应用容器加到数据库所在的网络里重新启动状态恢复正常。这个排查不到十五分钟但如果一上来就重启整个服务栈不仅浪费时间还可能连带影响其他业务。这段经历给我最大的教训是容器排障要顺着“状态→日志→网络→配置”的顺序去查docker inspect输出的JSON虽然看起来长但里面每个字段都有意义。遇到问题先看日志和状态不要直接删容器重建除非你确认数据都接出来了。4.3 Kubernetes常用命令先记住这一组再扩展到了K8s环境命令的复杂度又上一个台阶。但无论集群多大最基本的排查闭环永远是这组kubectl get nodes kubectl get pods -A -o wide kubectl describe pod 名称 -n 命名空间 kubectl logs -f pod名称 -n 命名空间 --tail100 kubectl exec -it pod名称 -n 命名空间 -- bash kubectl top nodes kubectl top pods -n 命名空间kubectl get是入口先看全局状态-o wide能看到Pod被调度到了哪个节点、运行在哪个IP。describe是排查关键它会显示事件列表Pod卡在Pending、ImagePullBackOff、CrashLoopBackOff这些异常都会在这里留下原因。logs和exec相当于容器命令的K8s版本。kubectl top查看节点和Pod的资源实际占用是判断是否到了资源上限的直接依据。很多人一上来就背一堆K8s命令我觉得没必要。先把这组最基本的用熟遇到错误再看具体场景去扩展比如排服务发现用kubectl get svc、排配置用kubectl get configmap、看证书用kubectl get secrets。命令是查不完的关键是建立“先get看状态、再describe看原因、最后logs看日志”的排查习惯。4.4 两个高频K8s故障镜像拉不下来和启动就崩Pod最常见的一个异常是ImagePullBackOff字面意思是镜像拉取失败。执行kubectl describe pod xxx会看到具体原因可能是镜像地址拼写错误、仓库需要认证、镜像不存在或者节点无法访问镜像仓库。如果镜像没问题再看节点上能不能手动拉镜像crictl pull 镜像地址或docker pull这样可以区分是仓库认证问题还是网络问题。另一个高频异常是CrashLoopBackOff表示Pod启动后反复崩溃。这种问题kubectl logs是最直接的入口看应用启动日志报什么错。但有一个坑如果容器启动即崩溃日志可能还没来得及写就被回收这时候要加--previous参数kubectl logs pod名称 --previous查看上一次容器实例的日志。另外应用本身可能没有输出日志要靠kubectl describe pod里的Events判断比如Liveness探针失败、启动命令找不到文件等。先看日志、再看Events、最后看配置这个顺序能解决掉绝大多数的CrashLoop。5. 网络排查从ping不通到tcpdump抓包一条链路走下来网络问题绝对是运维面试和实战里的常客。很多人一遇到网络不通就先去ping看到ping不通就一脸茫然。其实网络排查有清晰的层次从底层到顶层逐层确认大部分问题能在三分钟内定位到范围。这一节我按自己习惯的顺序从连通性、DNS、端口、抓包四个阶段把常用命令串起来。5.1 先明确故障现象再决定从哪一层开始查接到“网络不通”的反馈第一件事不是敲命令而是问清楚从哪到哪不通是外部用户访问不了还是服务器之间互相访问不了是业务A访问业务B不通还是整台服务器对外都不通故障范围直接决定排查起点。比如“只能访问A服务器不能访问B”那大概率不是网络设备问题而是B服务器上的服务或防火墙配置问题。确认范围后我习惯从三层开始逐层往上先确认链路通不通再确认域名解析对不对然后确认端口是否监听、服务是否存活最后如果前面都正常但业务还是异常再上抓包看协议层面有没有问题。这个顺序背后是“每一层都能缩小一半范围”的思路总比在某一层死磕要高效。5.2 连通性、路由、DNS三个方向三条命令链路层和网络层的检查命令是ping -c 4 目标IP mtr -rw 目标IP traceroute -n 目标IPping通了说明三层连通正常ping不通则要分两种情况目标IP本身不可达或者中间有设备拦截了ICMP。很多云环境默认不响应ping所以“ping不通”不等于“网络不通”这一点特别容易误判。mtr是我强烈推荐的工具它结合了ping和traceroute的功能能实时看到每一跳的丢包率和延迟判断瓶颈在哪一段路由。traceroute -n用IP而非域名显示每一跳地址方便确认经过的路径是否符合预期。DNS这块用dig 域名 nslookup 域名 cat /etc/resolv.confdig的输出比nslookup更清晰重点看ANSWER SECTION返回的IP是不是预期值。如果域名解析出来一个完全陌生的IP十有八九是DNS被污染或指向了错误的服务。可以再用dig 8.8.8.8 域名这种指定公共DNS的方式做对照判断是本地DNS服务器的问题还是域名本身解析就异常。5.3 端口通了服务没通别被假象骗了ping通不代表业务通很多服务是用TCP端口通信的所以端口层检查必不可少telnet 目标IP 端口 nc -vz -w 3 目标IP 端口 ss -lntp lsof -i:端口号telnet 目标IP 端口是传统方式连上会显示Connected端口不通会卡住或提示Connection refused。nc -vz -w 3加了超时时间更适合脚本化检查。在本机检查服务是否监听用ss -lntp看监听地址是0.0.0.0还是127.0.0.1——后者会导致外部访问不通这是非常常见的配置问题服务只监听了回环地址外部请求自然被拒。如果端口本地能监听、外部telnet却不通接下来就要查防火墙和云安全组。命令是iptables -L -n、firewall-cmd --list-all、ufw status每套系统的命令不一样。云环境还要在控制台确认安全组规则。很多时候数据库连不上查到最后都是安全组没有放行对应端口这种坑踩一次就长记性了。5.4 tcpdump抓包把问题从“感觉”变成“实锤”层级检查都做过、端口没问题、业务却还是异常这时候只有抓包能一锤定音。tcpdump的基本用法我整理成四个常用姿势tcpdump -i eth0 -nn port 8080 -c 100 tcpdump -i eth0 -nn host 1.2.3.4 tcpdump -i eth0 -nn -s0 -w /tmp/capture.pcap port 3306 tcpdump -i any -nn tcp port 80 and host 1.2.3.4-i指定网卡-nn不做域名和端口解析-s0抓取完整数据包-w写入文件-c指定抓多少个包后自动停止。实际使用中为了防止终端被数据包刷屏我通常先-c 100抓少量包确认现象再用-w落盘后拿Wireshark分析。一次真实案例两台服务器之间调用接口间歇性超时ping通、端口通、应用日志也没有明显报错。我在超时频繁的服务器上抓包发现TCP包存在大量重传而且重传间隔越来越长。这就说明网络存在丢包或延迟抖动方向直接指向物理链路或防火墙策略后来配合网络团队在交换设备上找到了原因。没有抓包数据这个问题不知道还要排查多久。6. 数据库和中间件几条保命命令要刻进肌肉服务器、容器、网络都排查完业务还是慢下一步就要看数据层和中间件了。MySQL、Redis是现在运维接触最多的组件我不讲复杂的调优只讲日常用得最多、能救急的几条命令和它们背后的判断逻辑。6.1 MySQL急救三查连接、慢查询、主从状态MySQL出问题我按这个顺序查mysql -h 127.0.0.1 -u root -p -e SHOW PROCESSLIST; mysql -h 127.0.0.1 -u root -p -e SHOW GLOBAL STATUS LIKE Threads_connected; mysql -h 127.0.0.1 -u root -p -e SHOW VARIABLES LIKE slow_query_log%;SHOW PROCESSLIST是我遇到MySQL性能问题第一个执行的命令它能看到当前所有连接正在执行的SQLState字段如果是Sending data、Copying to tmp table、Waiting for table lock这些基本都是性能问题的信号。Threads_connected显示当前连接数如果接近max_connections上限说明连接池配得太大或存在慢查询导致连接堆积。慢查询日志配置需要打开参数是slow_query_logON和long_query_time2超过2秒的SQL会被记录下来。排查时用mysqldumpslow -s t -t 10 慢日志路径看TOP10最慢的SQL这个输出是所有DBA的必读数据。主从架构还要定期看一眼主从状态mysql -e SHOW SLAVE STATUS\G; | grep -E Slave_IO_Running|Slave_SQL_Running|Seconds_Behind_Master只要看到IO线程或SQL线程有一个不是Yes或者Seconds_Behind_Master一直在涨主从链路就已经出问题了需要尽快处理。6.2 Redis排查info、slowlog、bigkeys三件套Redis是缓存界的主力它出问题时通常是内存暴涨、缓存穿透、慢命令阻塞。我用的排查命令redis-cli info memory redis-cli info stats redis-cli slowlog get 20 redis-cli --bigkeysinfo memory看used_memory和maxmemory的对比如果used_memory接近maxmemory说明需要关注淘汰策略了。info stats里有个instantaneous_ops_per_sec瞬时QPS能快速判断Redis当前压力。slowlog get 20查看最近20条慢命令重点看执行耗时和命令内容经常会发现线上有KEYS *这种阻塞命令一颗老鼠屎坏一锅汤生产环境一定要禁止。redis-cli --bigkeys是分析大key的利器它会遍历整个Redis并统计哪些key占用的内存大、哪些集合类型的元素多。大key是Redis的定时炸弹不仅占内存删除时还可能阻塞主线程。以前排查过一台Redis频繁卡顿用这个命令发现有哈希列表有上百万个字段客户端每次读取都毫无必要地拉全量和开发沟通后把数据结构改了问题彻底解决。6.3 几个硬核提醒高峰期的操作要克制数据库和中间件上最容易犯的错误是一出问题就重启、或者执行高危命令。我在MySQL上见过有人执行DROP DATABASE最后靠备份恢复在Redis上见过有人在生产环境执行FLUSHALL把整个缓存清空导致数据库被流量打爆。这些命令在测试环境随便玩生产环境务必谨慎执行前至少要确认是不是有这个权限、是不是当前业务低峰、有没有完整的恢复方案。另一个提醒是redis-cli monitor这类命令它会把Redis收到的每个命令都打印出来排障时确实好用但在高并发线上环境打开monitor会显著增加Redis负载。我的经验是打开之前先跑info stats看当前ops如果QPS已经很高就不要再用monitor去火上浇油。可以先通过慢日志和bigkeys做一个初步判断非必要不上monitor。7. 把命令变成肌肉记忆的笨办法但真的有用聊了这么多命令和场景我想最后落回一个话题怎么让这些命令真正变成自己的东西。说实话包括我在内没有哪个运维能记住所有命令的参数关键是建立一套属于自己的记忆和组织方式。这一节我分享几个实测有效的方法算是给全文做一个不是总结的总结。7.1 按场景记命令而不是按字母表背命令我刚开始也买过Linux命令大全这类书背到后面发现完全记不住因为脱离场景的命令没有锚点。现在我的知识组织方式完全不同以“场景”为索引。比如“磁盘满了”是一个场景它下面挂着df、du、lsof、journalctl、logrotate这一组命令“收到CPU告警”是一个场景它下面挂着top、mpstat、pidstat、pidstat排查链路。问题来了能想到对应的场景场景能带出命令这才叫肌肉记忆。这种组织方式和搜索引擎正好相反搜索引擎是“我看到报错搜解决方案”而场景记忆是“我先判断这是什么类型的问题、该用哪一套工具”。熟练度和排查速度的差距就是这么拉开的。所以我建议你也准备一个自己的命令速查文档按“故障现象→排查命令→判断标准→常见解决方案”的结构去维护半年之后你会发现这个文档比任何公开的命令大全都值钱。7.2 工具可以帮你偷懒但别偷掉判断力命令行有好多现成工具可以帮我们减少记忆负担。tldr工具提供了极简版命令帮助适合快速回忆某个工具的用法cheat工具更直接能显示常用命令的可执行示例比如cheat tar直接给出各种打包解压的写法。这两个我都装了但它们只解决“想不起来参数”的问题不解决“不知道该用什么命令”的问题——后者只能靠场景积累。history命令也可以当工具用。我不会刻意清理history反而会留着它遇到相似问题时先history | grep 关键词看看以前是怎么处理的。同时我会把每天执行过的重要命令追加到一个markdown笔记里标注日期和场景。这些记录既是复盘素材也是写交接文档的第一手资料。7.3 几条压箱底的组合命令日常排查能省一半时间最后分享几个我几乎每天都会用到的组合写法。第一个是快速定位日志中的异常tail -f /var/log/app.log | grep --line-buffered -E ERROR|EXCEPTION|TIMEOUT--line-buffered保证grep能实时输出而不是等缓冲区满了才打印。第二个是在多个服务日志里搜关键词grep -rn 关键字 /var/log/ --include*.log | head -50第三个是批量查看多个同类型进程的状态防止漏掉异常ps -eo pid,stat,cmd | grep 服务名 | grep -v grep查看进程状态列STAT时如果出现D状态不可中断睡眠进程可能在等待磁盘IO要结合iostat进一步排查出现Z状态僵尸进程则需要找父进程处理。另外还有一个很有用的习惯在高危命令前加echo演练一遍比如echo rm -rf /var/log/old/*先确认路径没问题再执行真正的命令能防住不少手滑事故。7.4 一些更深的体会留给能读到这里的你写了这么多如果只留一句话我想说运维常用命令的价值不在于命令本身而在于你面对故障时的思路是否清晰。命令是工具思路才是决策。工具可以随时查手册但“从现象判断方向、从方向选择命令、从输出得出结论”这个能力需要靠一次次真实排障去打磨。这些年我带过不少新人我也发现一个现象喜欢把命令整理成文档、愿意记录每次排障过程的人成长速度往往更快。因为写下来的过程其实就是逼自己把“不知道”变成“知道”的过程。下次当你打开终端不知道敲什么命令时先问自己一句我现在面对的是什么类型的问题答案自然就会从这篇文章整理过的那些场景里浮出来。
返回列表