CPU 使用率飙升到 100%(资源)
现象:服务器变慢,页面响应超时,用户投诉
1
运行 top 或 htop
实时查看所有进程的 CPU 占用排行。按 P 键按 CPU 降序排列,找到占用最高的进程和它的 PID(进程ID)。
2
用 ps aux | grep [PID] 查进程详情
确认这是哪个程序、哪个用户启动的、启动参数是什么,从而判断它是业务进程还是陌生进程。
3
用 strace -p [PID] 看系统调用
如果是业务进程,strace 能看到它在反复做什么操作(如死循环读文件、死循环计算),帮助定位代码问题。
4
判断是否是挖矿木马
如果进程名陌生、用户是 nobody/www-data 、或路径在 /tmp 下,高度怀疑是入侵植入的挖矿程序。立刻 kill -9 [PID] 并排查入侵路径。
根本原因分三类:① 代码 bug(死循环)② 流量突增(正常业务压力)③ 被入侵(挖矿)。排查顺序就是从"是否认识这个进程"开始。
服务被 OOM Killer 杀掉(资源)
现象:服务突然挂掉,日志末尾是 Killed,没有异常堆栈
1
运行 dmesg | grep -i "oom"
dmesg 是内核日志。OOM Killer 是 Linux 内核在内存不足时主动杀进程的机制,它会在内核日志里留下记录,说明杀了哪个进程、当时内存状态。
2
查看 /var/log/messages 或 journalctl -k | grep -i oom
systemd 系统用 journalctl,传统系统看 /var/log/messages,两者都能找到 OOM 事件的详细记录。
3
确认是内存泄漏还是配置不足
用 free -h 查总内存。如果内存本来就小、业务数据量大 → 加内存或加 Swap。如果内存够但进程越占越多 → 代码内存泄漏,需要 profiling 排查。
4
临时加 Swap 缓解:fallocate -l 2G /swapfile
Swap 是用磁盘模拟内存,速度慢但能防止 OOM。Java 服务尤其容易吃内存,临时加 Swap 能买时间排查,但不是根本解法。
为什么日志只有 "Killed" 没有报错?因为进程是被内核从外部强杀的(SIGKILL),进程本身来不及写任何东西就没了。这是 OOM 的典型特征。
磁盘满了但 du 找不到大文件(资源)
现象:df 显示 100%,服务写入失败,但 du -sh /* 加起来对不上
1
运行 df -h 确认哪个分区满了
df 显示的是文件系统实际占用,du 显示的是目录里可见文件的大小。两者不一致时,说明有"幽灵空间"。
2
运行 lsof | grep deleted
这是核心原因:文件被 rm 删除后,如果还有进程(如 Nginx、Java)持有这个文件的句柄(文件描述符),inode 不会释放,空间也不会还给操作系统。lsof 能看到这些"已删除但仍占空间"的文件。
3
重启相关进程来释放句柄
对持有这个 deleted 文件的进程执行 systemctl restart [服务名],进程重启后句柄释放,空间才真正还给 OS。
4
日常:用 du -sh /* | sort -rh | head -20 找真实大目录
从根目录往下逐层找最大目录,通常是 /var/log(日志堆积)或 /var/lib/docker(容器镜像)。
陷阱:很多人以为 rm 就彻底删了。实际上 Linux 的删除只是"断开文件名和 inode 的链接",只要还有进程持有 fd,数据和占用空间就不会消失。
本地通但外部端口访问不了(网络)
现象:curl localhost:80 成功,但外网 IP 访问 80 端口超时
1
确认服务监听地址:ss -tlnp | grep 80
关键点:0.0.0.0:80 表示监听所有网卡(外网可达),127.0.0.1:80 表示只监听本机回环(外网完全访问不到)。Nginx 默认监听 0.0.0.0,但配置错误时可能只绑定了本地。
2
检查系统防火墙:firewall-cmd --list-all 或 iptables -L
即使服务监听了 0.0.0.0,系统防火墙也可能把外部流量挡在外面。需要确认 80/443 端口在防火墙规则里是放行的。
3
检查云平台安全组
腾讯云、阿里云等有"安全组"是在网络层面的防火墙,比系统防火墙更靠前。安全组没开放端口,数据包根本到不了服务器,所以系统内 iptables 放行也没用。
4
从外部测试端口:telnet [公网IP] 80
如果 telnet 直接拒绝(Connection refused)= 到了服务器但端口没开;如果超时(timeout)= 安全组/网络层拦截了,根本没到服务器。两种现象对应不同的排查方向。
排查链:监听地址 → 系统防火墙 → 云安全组,三层都要检查,卡在哪层现象略有不同。
疑似 DDoS / SYN Flood 攻击(网络)
现象:netstat 大量 SYN_RECV,服务响应极慢甚至无响应
1
确认攻击:netstat -an | grep SYN_RECV | wc -l
正常情况下 SYN_RECV 数量极少。SYN Flood 的原理是攻击方大量发 SYN 包但不完成三次握手,服务器队列被占满,正常连接进不来。
2
开启 SYN Cookie:sysctl -w net.ipv4.tcp_syncookies=1
SYN Cookie 是内核级防御。开启后,服务器不会为半开连接分配资源,而是用一个加密 cookie 来验证,使 SYN Flood 失效。
3
用 iptables 限速或封攻击 IP
iptables -A INPUT -p tcp --syn -m limit --limit 100/s -j ACCEPT 限制每秒新 SYN 包数量,超出的丢弃。如果攻击来自少数固定 IP,可以直接 DROP 封掉。
4
大流量攻击联系云厂商开启 DDoS 防护
如果攻击流量超过服务器带宽(比如几十 Gbps 的流量攻击),服务器本身无法处理,必须在上游进行流量清洗(腾讯云 DDoS 高防 IP 等)。
SYN Flood 是四层攻击,iptables 在系统内处理,如果带宽已经被打满,iptables 规则也来不及生效。大规模攻击必须靠上游清洗。
Nginx 返回 502 Bad Gateway(服务)
现象:用户看到 502,Nginx 进程是运行的,之前好好的
1
理解 502 的含义
502 = 网关错误。Nginx 本身正常,但它作为反向代理去连后端服务(Java/Python/PHP)时失败了。原因要去后端找,不是 Nginx 的问题。
2
检查后端服务是否在运行
systemctl status [后端服务名] 或 ps aux | grep java。后端进程崩溃是 502 最常见的原因。
3
查后端服务的日志
进程在但 502 也可能发生(如后端启动了但端口没监听成功、后端代码抛了异常导致无法响应)。日志里会有具体报错。
4
核对 Nginx upstream 配置:nginx -t
确认 nginx.conf 里 proxy_pass 指向的地址和端口与后端实际监听的一致。端口写错(如后端跑 8080,配置写了 8081)也会 502。
区分常见状态码:404 = 资源不存在(Nginx 正常);502 = 后端挂了(找后端);504 = 后端太慢超时(性能问题);500 = 后端代码报错(看后端日志)。
Crontab 定时任务没有执行(服务)
现象:写了 cron 表达式,到时间了任务没跑,也没报错
1
确认 cron 服务在运行:systemctl status cron 或 crond
cron 服务本身没启动,所有任务都不会执行。Ubuntu 叫 cron,CentOS 叫 crond,名字不同。
2
检查 cron 表达式语法
cron 表达式是 分 时 日 月 周 五个字段。常见错误:* * * * * 是每分钟,0 2 * * * 是每天凌晨2点。可以用 crontab.guru 网站验证。
3
检查脚本是否有执行权限:chmod +x /path/to/script.sh
cron 不会像手动运行一样报"Permission denied",它只是静默失败。脚本没有 x 执行权限时任务就是不跑。
4
在 cron 里用绝对路径
cron 的运行环境没有普通 shell 的 PATH(比如没有 /usr/local/bin)。脚本里写 python3 可能找不到,要写成 /usr/bin/python3。
5
把输出重定向到日志:cmd >> /tmp/cron.log 2>&1
cron 默认不输出任何东西,也不报错。加上日志重定向,下次出问题就能看到究竟发生了什么。这是最重要的 debug 手段。
新手最常踩的坑:脚本在终端里手动运行没问题,cron 里就是不跑。99% 是路径问题(PATH 环境变量不同)或权限问题。
SSH 被大量陌生 IP 爆破(安全)
现象:/var/log/auth.log 里大量 Failed password for root,来自不同 IP
1
安装 fail2ban:apt install fail2ban
fail2ban 监控日志,某个 IP 在短时间内连续登录失败 N 次,就自动用 iptables 封禁它。自动化处理,不用人工盯着。
2
改 SSH 端口(改成非 22 的高位端口)
互联网上大量自动扫描工具只扫 22 端口。改成如 12345,扫描工具就找不到了,爆破流量立刻减少 99%。治标但有效。
3
禁用密码登录,改用密钥:PasswordAuthentication no
密钥登录的原理是非对称加密。攻击者就算知道用户名,没有私钥就无法登录,爆破密码完全无效。这是最根本的防御措施。(你已经在做了)
4
在 sshd_config 里禁止 root 直接登录:PermitRootLogin no
攻击者通常第一个试 root。禁止 root 远程登录后,即使密码泄露也无法直接拿到最高权限,需要先登普通用户再 sudo。
防御纵深原则:改端口(减少扫描)+ 密钥登录(爆破无效)+ fail2ban(自动封 IP)+ 禁 root 登录(降低危害),四层叠加,远比只做一层安全。