CPU / 内存
内存泄漏如何排查?
思路:遵循 “自上而下+工具链” 的思路
- 确认现象:用
free -h看available是否持续走低,用vmstat 1看si/so是否频繁交换。 - 定位进程:用
ps aux --sort=-%mem | head -n 10或top按M排序,找到内存占用最高的 PID。 - 深入分析(按语言选工具):
- Java 应用:用
jmap -dump导出堆转储,配合 MAT 分析支配树和 GC Roots 引用链,定位泄漏对象。 - C/C++ 应用:可用
memleak(eBPF) 追踪未释放的分配调用栈,或valgrind在测试环境分析。
- Java 应用:用
- 判断类型:结合 GC 日志判断是堆内存泄漏、元空间泄漏还是直接内存泄漏,再针对性修复
服务器CPU使用率飙升,如何排查?
思路:遵循 “自上而下+工具链” 的思路
标准排查流程:系统级/进程→线程→栈→系统调用
- 系统级分析:
top按P排序,或ps aux --sort=-%cpu | head -n 10,找到%CPU最高的异常进程 PID。- 使用
vmstat 1观察r(运行队列)是否长时间大于CPU核数,若sy(内核态占用)飙升,可能是有频繁的上下文切换或中断。 - 排查是否遭受了 DDoS/恶意攻击(大量握手请求占满CPU软中断
si)。
- 使用
- 转为线程级分析:
- 执行
top -H -p [PID]找出该进程内最耗CPU的线程ID(十进制)。(-H 显示详细线程,-p 指定PID) - 将线程ID转换为16进制:
printf "%x\n" [线程ID]。
- 执行
- 抓线程栈:
- JAVA:使用
jstack [PID] | grep -A 20 [16进制线程ID]直接查看该线程正在执行的代码堆栈,定位到具体类和方法。 - 使用
perf top -p [PID]查看 CPU 在执行哪些内核/用户态函数,精细定位热点函数(如垃圾回收GC线程,或者正则计算)
- JAVA:使用
- 系统调用:如果栈显示卡在
read/write/futex等,使用strace -p [PID]跟踪进程的系统调用,看是否卡在某个内核调用上(如不断重复读写文件)。
服务器频繁发生 OOM Kill,但业务进程内存占用并不高,如何排查?
根因:通常是 内核 slab 内存(内核缓存)暴涨 或 某个进程疯狂申请匿名内存页(如内存泄漏)但被漏看。
排查步骤:
dmesg -T | grep -i "Out of memory"查看 OOM 发生时被杀的进程名和oom_score。- 查看系统内存细分:
cat /proc/meminfo关注Slab、SReclaimable、KernelStack。若Slab异常大,用slabtop看是哪个内核对象占用(如dentry、inode_cache暴涨,说明文件句柄泄露)。 - 统计所有进程实际占用总和:
ps aux | awk '{sum+=$6} END {print sum/1024 " MB"}'(单位 KB),若总和远小于总内存,差值就是内核占用了。 - 检查是否有 内存超卖 情况(如 K8s Pod 的 limits 设置过小,虽然物理内存够,但 cgroup 限制内 OOM)。
vmstat -s查看pages paged in/out,确认是否有频繁换页加剧内存压力。
服务器负载(Load Average)飙升,但 CPU 使用率很低,什么原因?如何排查?
现象:top 看 load average 高达几十,但 %us 和 %sy 都很低。
根因:大量进程处于不可中断睡眠状态(D 状态),通常是因为 I/O 阻塞(磁盘/网络/外部设备)。
排查步骤:
top按D键排序,查看处于D状态的进程数量。ps aux | awk '$8=="D" {print $2,$NF}'列出所有 D 状态进程。strace -p [PID]看卡在哪个系统调用(通常是read/write磁盘或NFS)。iostat -x 1查看%util和await,若接近 100% 或await极高,说明磁盘 I/O 已饱和。- 若磁盘正常,检查是否有 NFS 挂载超时:
df -h卡住不动说明 NFS 服务端不可达。
存储
磁盘空间报警,但 du 统计的总大小远小于磁盘已用空间,怎么回事?
根因:文件被删除但进程仍持有句柄,空间未真正释放;或 inode 耗尽。
排查步骤:
- 先检查 inode:
df -i,如果IUse%100%,说明小文件太多,用find / -type f | wc -l定位目录。 - 若 inode 正常,查句柄泄露:
lsof +L1列出所有已删除但未释放句柄的文件(标记为(deleted))。 - 找到占用进程后:
ls -l /proc/[PID]/fd/ | grep deleted确认,重启该进程即可释放空间。 - 若不重启,可
echo > /proc/[PID]/fd/[fd号]清空文件(风险操作,需确认业务影响)。
网络
客户端无法访问服务器8080端口,怎么全链路排查?
思路:从服务器着手,从物理层 → 网络层 → 传输层 → 应用层逐层递进。
排查步骤:
- 服务器本机确认(物理层):
netstat -tlnp | grep 8080或ss -tlnp | grep 8080,确认进程是否在监听0.0.0.0还是127.0.0.1(后者仅本机可访)。 - 服务器防火墙(网络层):
iptables -L -n | grep 8080和firewall-cmd --list-all,检查是否有 DROP/REJECT 规则。 - 连通性测试(传输层):从客户端
telnet [IP] 8080或nc -zv [IP] 8080看是否通;不通则逐跳traceroute看丢在哪。 - 抓包分析(传输层):
tcpdump -i any port 8080 -nn,看三次握手是否完成(SYN→SYN+ACK→ACK)。若只有 SYN 无响应,说明服务端未回包;若回 RST,说明进程拒绝连接(可能是 backlog 满了或应用层拒绝)。 - 应用层:
curl -v [IP]:8080看 HTTP 状态码,或查看应用日志是否有Connection refused异常。
无法 Ping 通目标主机/域名,如何排查?
思路:若域名不通 IP 通,直接定位到 DNS 故障。都不通则按分层排查思路。从下往上(物理层 → 网络层 → 传输层 → 应用层),逐层缩小范围。
简洁版:先确认本地网卡和 IP 配置,再 ping 网关判断是否局域网问题;若网关通,用 traceroute 定位丢包节点,同时检查本机防火墙;若域名不通 IP 通,定位到 DNS 故障,检查 /etc/resolv.conf,ping 域名服务器确定是域名服务器不可达还是解析问题;最后,考虑到很多生产环境出于安全考虑会主动禁 ICMP 协议,我会改用 telnet 端口探测 代替 ping。
第一层:自查(排除本地低级错误/物理层)
- 网络连通性:先 ping
127.0.0.1确认本机 TCP/IP 协议栈正常;再 ping 本机 IP(非 lo)确认网卡驱动正常。 - 网卡状态:
ip a或ifconfig确认网卡是否UP,RUNNING;检查网线/WiFi(物理层)。
第二层:网关与路由(局域网/网络层)
- ping 网关:ping 默认网关(
ip route | grep default查),网关不通 → 问题在交换机/路由器/无线信号;网关通 → 问题在外网或目标端。 - traceroute 追踪:
- Linux:
traceroute -n [目标IP](加-n跳过 DNS 解析更快)。 - Windows:
tracert -d [目标IP]。 - 看在哪一跳 超时/星号,大概率是该节点路由丢包或防火墙拦截了 ICMP 包(很多云厂商安全组默认屏蔽 ICMP)。
- Linux:
第三层:防火墙/安全组拦截(传输层/网络层)
- 本机防火墙:
iptables -L -n -v | grep DROP看是否有 DROP 规则。firewall-cmd --state(CentOS 7+)或ufw status(Ubuntu)。
- 如果有目标主机访问权,检查:
- 云安全组/ACL:登录云控制台,检查目标机器的 入方向安全组 是否放行了 ICMP 协议(允许
type 8入站)。 - 目标主机防火墙:目标主机如果开启
iptables且 DROP 了 ICMP,本地 ping 会超时(但业务端口如 80/443 可能依然通,要区分)。
- 云安全组/ACL:登录云控制台,检查目标机器的 入方向安全组 是否放行了 ICMP 协议(允许
第四层:DNS 解析问题(应用层)
现象:ping 域名不通,但 ping IP 通
- 排查命令:
cat /etc/resolv.conf检查 DNS Server 配置(如114.114.114.114或内网 DNS)。- ping 域名服务器确定是域名服务器不可达还是解析问题
- 检查
/etc/hosts是否写死了解析(被错误覆盖)。
- 如果有装
nslookupdig可以使用dig @8.8.8.8或dig [目标域名]排查
第五层:目标服务存活(终极确认)
注意:很多安全策略会 禁止 ICMP 协议(ping),但 业务端口(如 80/443)是通的。
- 此时应该用 端口探测 代替 ping:
telnet [目标IP] [端口]或nc -zv [目标IP] [端口]- 如果端口通但 ping 不通 → 属于正常现象(云厂商/运维策略屏蔽 ICMP)。
- 如果端口也不通 → 目标服务挂了,或目标主机本身无法访问。
综合
如何查看服务/进程是否正常运行?
原则:进程在 ≠ 服务正常。 要分层判断:状态 → 进程 → 端口 → 健康探针 → 日志。
- 托管状态:systemd 用
systemctl is-active+is-enabled,SysV 用service xxx status; - 进程:没有托管就用
pgrep -af/ps -ef; - 端口:
ss -lntp确认监听; - 健康探针:
curl打业务健康接口,这才是真验证; - 日志:
journalctl -u xxx或日志文件,看有无报错。
只做①②不算查完,必须做到④才算真健康。
参考 Shell 脚本
#!/bin/bash# check_service.sh <name> [port] [health_url]NAME="$1"; PORT="$2"; URL="$3"[ -z "$NAME" ] && { echo "Usage: $0 <name> [port] [health_url]"; exit 2; }FAIL=0
# systemd 优先if systemctl list-unit-files 2>/dev/null | grep -q "^${NAME}\.service"; then echo ">>> systemd unit: $NAME.service" systemctl is-active --quiet "$NAME" \ && echo "[OK] active" \ || { echo "[FAIL] not active"; FAIL=1; } systemctl is-enabled --quiet "$NAME" \ || echo "[WARN] not enabled (won't start on boot)" PID=$(systemctl show -p MainPID --value "$NAME")else echo ">>> fallback: process check" if pgrep -f "$NAME" >/dev/null; then PID=$(pgrep -f "$NAME" | head -1) echo "[OK] process PID=$PID" else echo "[FAIL] process not found"; FAIL=1; PID="" fifi
# 端口if [ -n "$PORT" ]; then ss -lntp 2>/dev/null | grep -q ":$PORT " \ && echo "[OK] port $PORT listening" \ || { echo "[FAIL] port $PORT not listening"; FAIL=1; }fi
# 健康探针if [ -n "$URL" ]; then CODE=$(curl -s -o /dev/null -w "%{http_code}" --max-time 5 "$URL") [ "$CODE" = "200" ] \ && echo "[OK] health $URL -> 200" \ || { echo "[FAIL] health $URL -> $CODE"; FAIL=1; }fi
[ $FAIL -eq 0 ] && echo "=== HEALTHY ===" || echo "=== UNHEALTHY ==="exit $FAIL恢复
rm -rf / 误操作或误删重要文件后,怎么恢复(前提是进程未重启)?
核心原理:Linux 中文件名和 inode 分离,文件删除只是移除目录项,只要进程还在打开该文件,数据块未被回收。
恢复步骤(假设误删 /var/log/nginx/access.log):
- 立即停止写入:
lsof | grep deleted找到仍持有该文件句柄的进程(nginx 的 worker 进程)。 - 查看 fd 路径:
ls -l /proc/[PID]/fd/找到对应 fd 编号(如 4),显示为/var/log/nginx/access.log (deleted)。 - 重定向恢复:
cat /proc/[PID]/fd/4 > /var/log/nginx/access.log将文件内容原样拷回。 - 安全操作:通过 kill -HUP [PID] 重新加载配置让进程重新打开新文件句柄。
- 注:若进程已重启,则需依赖 extundelete 或 TestDisk 等工具做文件系统级别的恢复,但成功率取决于是否立即卸载分区并停止写入。
分享文章
生成精美分享图或复制链接,与更多人分享本文。
继续阅读
换条路线
从其他文章中稳定抽取
最后更新于 ,距今已过 42 天
部分内容可能已过时