←
Blog
Awshgreen
archive
Article · 2026-09-22

低配 VPS 排障手册:磁盘、内存、端口、日志与 DNS

低配服务器出问题时,通常不是缺少某个神秘优化,而是磁盘、内存、端口、日志和 DNS 中有一个环节已经失控。下面这份清单按“先看现象,再缩小范围”的顺序整理,适合 Debian、Ubuntu 这类常见发行版。

1. 先确认磁盘是不是满了

df -hT
df -ih

df -hT 看容量和文件系统类型,df -ih 看 inode。磁盘容量还有很多,但 inode 用完时,同样无法创建新文件。

找出占空间最多的一级目录:

sudo du -xhd1 / 2>/dev/null | sort -h
sudo du -xhd1 /var 2>/dev/null | sort -h

-x 可以避免跨到其他挂载点。确认大目录后再继续向下查,不要直接对整个根目录做删除操作。

systemd 日志也可能占据不少空间:

journalctl --disk-usage

如果已经确认日志保留策略过长,可以按时间清理,例如:

sudo journalctl --vacuum-time=14d

清理日志前先确认是否有审计或故障复盘需求。更好的长期做法是设置持久化日志和合理的容量上限,而不是每次爆满后手动救火。

2. 内存不足时不要只看“剩余内存”

free -h
swapon --show
ps aux --sort=-%mem | head -n 15

Linux 会把空闲内存用于缓存,所以 free 一栏很小不一定等于内存不足。重点看 available、swap 是否持续增长,以及哪个进程在不断变大。

如果只有 1~2 GB 内存,应用进程数比“理论并发数”更重要。Gunicorn、Node、Java 等服务都可能因为 worker 数过多而瞬间吃光内存。先把 worker 数降下来,再观察响应时间,不要用增加进程来掩盖慢查询或内存泄漏。

查看 OOM 痕迹:

sudo journalctl -k -g 'out of memory|oom|killed process' --no-pager

如果确实发生 OOM,先记录被杀的进程和发生时间,再决定是限制并发、修复泄漏还是增加内存。盲目增加 swap 只能延后问题,不能让程序凭空获得更多 CPU。

3. 端口冲突和公网暴露

查看监听端口:

sudo ss -lntup

重点区分:

  • 127.0.0.1:PORT:只接受本机连接。
  • 0.0.0.0:PORT:可能接受所有 IPv4 网卡连接。
  • [::]:PORT:可能接受所有 IPv6 网卡连接。

数据库、管理面板和应用后端通常不需要绑定公网。把它们限制到本机或内部网络,往往比额外加一条防火墙规则更不容易忘记。

查看某个端口由谁占用:

sudo lsof -nP -iTCP:8000 -sTCP:LISTEN

4. 服务状态和日志一起看

systemctl --failed
sudo systemctl status nginx --no-pager
sudo journalctl -u nginx -b -n 100 --no-pager

status 适合看当前状态和最近几行,journalctl 适合按启动批次、时间和服务筛选。应用反复重启时,先查完整错误上下文:

sudo journalctl -u example-app.service --since '30 min ago' --no-pager

Nginx 改配置时,始终先测试:

sudo nginx -t
sudo systemctl reload nginx

reload 通常比直接 restart 更适合只改配置的场景,因为它会让旧 worker 处理完已有请求后退出。配置测试失败时不要 reload,先修语法或路径问题。

5. 从本机到公网分层测试

服务访问失败时,不要一上来反复刷新浏览器。按层测试更快:

# 应用本机是否响应
curl -v http://127.0.0.1:8000/health

# Nginx 本机是否响应
curl -I -H 'Host: example.com' http://127.0.0.1/

# 域名解析到了哪里
dig +short example.com

# 外部 HTTPS 返回什么
curl -I https://example.com/

如果第一步失败,问题在应用;第一步成功、第二步失败,优先看 Nginx;第二步成功、第三步异常,检查 DNS;前三步都正常而外部失败,再看防火墙、TLS、CDN 或运营商网络。

6. 几个不显眼但很有用的命令

查看最近一天改过的配置文件:

sudo find /etc -type f -mtime -1 -print 2>/dev/null

查看进程树:

ps -eo pid,ppid,user,stat,etime,cmd --forest

查看文件描述符限制:

ulimit -n
systemctl show example-app.service -p LimitNOFILE

查看某个服务实际加载了哪些环境变量和启动命令:

systemctl cat example-app.service
systemctl show example-app.service -p ExecStart -p EnvironmentFiles

这些命令的共同点是“只读”。排障前先收集证据,通常比直接重启、清日志或删除缓存更安全。

7. Shell 小习惯,能减少很多事故

脚本中使用严格模式:

set -eu

变量加引号,删除前先打印目标,路径参数用 -- 和命令分隔:

target='/srv/example-app/releases/old-version'
printf 'will inspect: %s\n' "$target"
find -- "$target" -maxdepth 1 -type f -print

不要把未确认的变量直接拼到递归删除命令里,也不要把带密码的命令行贴进公共聊天或文章。生产环境命令最好一条一条执行,每一步确认输出再继续。

一套五分钟排障顺序

1. df -hT / df -ih       磁盘和 inode
2. free -h / swapon      内存和 swap
3. ss -lntup             监听端口
4. systemctl --failed    失败服务
5. journalctl -u ...     服务日志
6. curl 127.0.0.1        应用本机
7. curl + Host            反向代理
8. dig / curl https       DNS 和公网

这套顺序不保证一次解决所有问题,但能把“服务器坏了”拆成几个可验证的小问题。对于一台小 VPS,稳定的排障习惯往往比一次性堆很多监控组件更有价值。

参考资料