服务器只读巡检脚本:部署前先给机器做个体检
一条命令输出系统、CPU、内存、磁盘、端口、容器与工具链的完整快照,全程只读不修改任何状态,适合部署前评估和定期巡检。
#为什么需要一个"只读"巡检脚本
部署前最常见的问题不是"装不上",而是装完才发现机器扛不住。而排查问题时,又常常因为随手改了配置,导致现场被破坏。
所以这个脚本的设计原则只有一条:只采集,不修改。
- 不安装任何软件包
- 不修改任何配置文件
- 不启停任何服务
- 不创建或删除任何文件
#脚本本体
完整脚本可以在文末下载,这里说几个设计上的关键点。
#每个区块独立分隔
用 set -uo pipefail 而不加 -e:
set -uo pipefail # 注意没有 -e
原因是巡检脚本里某些命令在特定系统上本来就会失败(比如 CentOS 没有 ufw)。加了 -e 会导致脚本中途退出,采集不完整。单条命令失败不应该影响整体。
#内存要看 available 而不是 free
这是最容易误判的一项:
free -h
# total used free shared buff/cache available
# Mem: 982Mi 399Mi 138Mi 10Mi 444Mi 432Mi
如果只看 free 列的 138 MB,会得出"内存快满了"的错误结论。实际上 buff/cache 的 444 MB 是文件缓存,随时可以释放,真正可用的是 available 列的 432 MB。
所以脚本里额外抓了内核视角的精确值:
grep -E 'MemTotal|MemAvailable|Committed_AS|CommitLimit' /proc/meminfo
MemAvailable 是内核算出的"不触发 swap 的前提下还能分配多少内存",这才是容器 OOM 判断的依据。
#端口占用要逐个确认
不是看"服务能不能起来",而是提前确认目标端口是否被占:
for p in 80 443 3306 6379 3000 8080; do
printf 'port %-5s: ' "$p"
ss -ltn | grep -q ":$p " && echo OCCUPIED || echo FREE
done
比启动服务失败后再回头查要高效得多。
#工具链就绪检查
部署 Node 项目时,原生模块编译需要 gcc、make、python3。缺了会报一堆看不懂的错误:
for t in curl wget git jq tar unzip lsof ss gcc make; do
printf '%-8s=' "$t"
command -v "$t" >/dev/null 2>&1 && echo OK || echo MISSING
done
提前知道缺什么,比部署到一半报错要省时间。
#怎么读结果
拿到输出后,按这个优先级判断:
| 指标 | 判断标准 | 不达标的后果 |
|---|---|---|
| 内存 available | Node 项目 ≥ 300 MB | 运行中随时 OOM |
| 磁盘剩余 | ≥ 10 GB | 日志写满导致服务崩溃 |
| Swap | 建议 ≥ 2 GB | 内存突发时直接杀进程 |
| 系统版本 | 是否已 EOL | 软件源失效、无安全更新 |
| glibc 版本 | Node 18+ 需 ≥ 2.28 | 官方二进制包跑不起来 |
关于系统 EOL 这一项要特别说明:EOL 不等于不能用,但要知道风险在哪。
以 Debian 10 为例,LTS 支持已经结束,这意味着:
apt-get update可能因为源地址失效而报错(可以换成归档源解决)- 不再有安全补丁,暴露的漏洞不会修
- 新版本软件(比如 PHP 8.3+)可能因为依赖库版本不够而装不上
如果机器上已经装好了需要的运行时(比如 Docker、Nginx),短期继续用是可行的,但要规划迁移时间点。
#定期巡检的建议
除了部署前,建议每月跑一次并保存输出,这样能看到趋势:
# 保存历史记录,便于对比
bash server-inspect.sh > /root/inspect-$(date +%F).txt 2>&1
重点关注三个趋势:
- 磁盘增长速率 —— 日志和备份是主要增长源,按趋势预估何时需要扩容
- 内存占用基线 —— 缓慢上涨通常意味着有泄漏
- 进程数量 —— 意外增多的进程可能是被入侵的信号
#小结
巡检脚本的价值不在于"跑了什么命令",而在于把判断标准固化下来。有了基准数据,才能回答"这台机器能不能跑这个服务"这种问题,而不是靠感觉。
脚本在文末可直接下载。
附件下载 共 1 个文件,点击直接下载
服务器只读巡检脚本
一条命令采集系统、CPU、内存、磁盘、Docker、端口与防火墙信息,不修改任何系统状态,适合部署前体检。