news 2026/9/8 8:28:35

服务器不稳定排查指南:从CPU、内存到网络的系统化定位方法

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
服务器不稳定排查指南:从CPU、内存到网络的系统化定位方法

我经常在线上问题群里看到这样的描述:“服务器没有挂,但接口时不时超时,重启一下又好一阵子,过几天又开始了。”这种问题往往最让人头痛,因为它既不像宕机那样定位明确,也不像代码报错那样有堆栈可以查。它表现出来的是“时好时坏”,是“偶发超时”,是“重启后短暂恢复”,而这种状态,就是本文要讨论的“不稳定服务器”。

本文是《不稳定服务器的统治》系列第二季。第一季我们重点解决“怎么从零了解一台服务器”,这一季的目标更直接:遇到一台不稳定的服务器,如何按照一套可复用的路径去排查,而不是靠猜和反复重启。内容会覆盖 CPU、内存、磁盘、网络四个核心维度的排查方法,也会补充虚拟化环境、云服务器、容器场景下常见的特殊坑点。

如果你是后端开发、运维工程师、SRE,或者正在自己折腾什么技术项目,这篇文章都值得跟着过一遍。读完你至少能回答三个问题:服务器负载到底看哪个指标?内存被打满之前系统日志里会留下什么?为什么网络明明通,接口还是超时?把这些问题的边界理清,不稳定服务器的统治就会被拉下马。

1. 服务器不稳定到底在说什么

1.1 不稳定不是彻底宕机,而是“时好时坏”

先给“不稳定服务器”下一个实用定义:一台服务器如果偶尔宕机、频繁重启,那是高可用问题;如果从某一刻开始持续性能下降,那是容量或性能瓶颈;而“不稳定”通常是间歇性异常,比如每过几十分钟出现一次超时,或者每天固定时段 CPU 飙升,又或者内存占用只涨不降,直到被杀进程后才恢复。

这种“时好时坏”的状态比彻底宕机更难处理,原因在于它的复现窗口很随机。你登录服务器时可能一切正常,load average 很漂亮,内存也没满,可业务方就是持续反馈“又卡了”。于是很多人陷入一个循环:出了问题先重启,重启后暂时恢复,恢复后没有进一步排查,直到下次再犯。这样下去,不稳定会变成常态,而且每次重启都会抹掉部分现场证据,后续根因分析更难做。

1.2 不稳定服务器的典型表现

从运维和开发的实际经验看,不稳定服务器的典型表现可以归纳为以下几类:

  • 平均负载忽高忽低,CPU 使用率有时冲到接近 100%,有时又很低。
  • 内存持续增长,最终触发 OOM(Out Of Memory)机制,进程被系统杀掉。
  • 磁盘接近写满,或者磁盘 IO 等待时间明显偏高。
  • 网络偶发丢包、TCP 重传增多,客户端频繁报连接超时。
  • 应用进程本身没有退出,但对外端口不可连接或响应极慢。
  • 服务器时间出现偏移,导致日志时间线错乱、定时任务执行异常。
  • 容器或虚拟机场景下,宿主机资源竞争导致指标异常。

这些表现往往不是独立的。比如磁盘 IO 被打满之后,业务线程全部卡在等待 IO,从外部看就是接口超时;内存被 OOM killer 干掉后,进程可能自动重启,从外部看就是“服务闪断了一下”。所以排查不稳定服务器时,不能只看一个指标,需要按照固定顺序把所有关键指标过一遍。

1.3 为什么服务器不稳定很难排查

难排查主要有三个原因。第一,很多服务器在上线初期没有配置监控,等到出问题时,现场已经被下一次重启或日志滚动覆盖。第二,排查手段不系统,很多人习惯登录服务器后先看 top,但 top 只能看到当下的瞬时状态,看不到几分钟前的峰值。第三,多个指标同时异常时,很难分辨因果。比如 CPU 高可能是某个业务进程导致,也可能是磁盘 IO 慢导致大量 D 状态进程堆积。

解决这个问题的关键,是建立一套固定的排查顺序,并且理解每个指标之间的关联。下面我们从排查前的准备开始,一步一步把链路打通。

2. 排查前必须准备的三件事

2.1 监控先行:没有指标就没有排查

排查不稳定服务器,最忌讳的就是等事情发生后再登录服务器。如果事前有监控数据,至少能回答几个关键问题:问题从什么时间开始?哪个指标先异常?持续了多久?反之,如果没有任何历史指标,排查基本就是大海捞针。

基础监控至少包括系统负载、CPU、内存、磁盘、网络、关键进程状态和系统日志。生产环境推荐使用 Prometheus 加 node_exporter 加 Grafana 的组合,也可以使用云厂商自带的监控平台。对于个人测试机或临时排查,可以先准备一个手动巡检脚本,快速收集现场信息。

#!/bin/bash # 文件路径:/usr/local/bin/server_check.sh # 服务器稳定性快速巡检脚本,建议配合 cron 每 5 分钟执行一次 echo "===== $(date '+%Y-%m-%d %H:%M:%S') 开始巡检 =====" echo "--- 负载与进程状态 ---" uptime top -b -n 1 | head -20 echo "--- 内存状态 ---" free -h echo "--- 磁盘容量 ---" df -h echo "--- 磁盘 inode ---" df -i echo "--- 系统日志中的 OOM / IO 错误 ---" dmesg -T 2>/dev/null | grep -iE 'oom|killed process|blocked for more than' | tail -20 echo "--- 正在监听的端口 ---" ss -tlnp echo "--- TCP 重传统计 ---" netstat -s | grep -i 'segments retransmited\|retransmited' || true

这个脚本里的每条命令都有明确作用。uptime看平均负载,top看进程和 CPU 状态,free -h看内存,df -hdf -i分别看磁盘容量和 inode,dmesg翻系统日志里的 OOM 和 IO 阻塞记录,ss -tlnp看当前监听的端口,netstat -s看 TCP 重传。出现不稳定时先跑一遍,很多问题都能直接暴露。

2.2 时间同步:所有日志的时间线必须一致

排查不稳定服务器时,有一件很容易被忽略但极其重要的事:时间同步。应用日志、系统日志、监控数据分布在多台服务器上,如果各自时间不一致,串时间线时会非常痛苦。常见的表现是:数据库日志显示某条 SQL 在 10:00:00 执行,应用日志却显示 10:03:00 才发起请求,中间这 3 分钟是时间差还是性能问题,根本说不清。

Linux 服务器推荐使用 chrony 替代传统 NTP 服务。配置文件位于/etc/chrony/chrony.conf,最小配置如下:

# /etc/chrony/chrony.conf 示例,server 地址请根据你的网络环境调整 server ntp.aliyun.com iburst server ntp.tencent.com iburst # 允许本地客户端同步自己的时间 local stratum 10 # 启动并设置开机自启 systemctl enable chronyd systemctl restart chronyd # 查看时间同步状态 chronyc sources -v chronyc tracking

如果你需要检查校时服务器(NTP 服务器)的 123 端口是否被防火墙关闭,可以尝试用nc -uvz <NTP服务器IP> 123测试 UDP 端口连通性,但 UDP 探测的结果不如 TCP 直观,更可靠的方式是直接在客户端执行chronyc sources -v,看^*标记是否出现。*表示当前已同步源,^表示该源可用。如果一直看不到同步源,再去检查防火墙和网络路由。

还要注意时区问题。如果服务器时区不对,即使时间同步成功,业务看到的日志时间也可能和预期不一致。可以用timedatectl set-timezone Asia/Shanghai设置时区,用timedatectl查看当前系统时间和时区信息。

2.3 建立变更记录:90% 的不稳定来自变更

监控和时间同步都是“事后取证”的基础,但真正能大幅缩小排查范围的,是变更记录。很多人排查到深夜,最后发现是昨天加了一个定时任务,或者升级了某个依赖包。可如果没有变更记录,所有可能性都只能靠猜。

这里说的变更不仅指代码发布,还包括系统内核参数调整、数据库配置修改、中间件版本升级、定时任务新增、防火墙规则变更、云资源规格调整等。建议哪怕是个人服务器,也用一个简单的 Markdown 文件记录每次变更的时间和内容。团队环境则应该借助发布平台或 CI/CD 系统的历史记录,保留每个环境的完整变更历史。这样当服务器开始不稳定时,第一步就可以对比“不稳定开始时间”和“最近变更时间”,如果高度重合,优先回滚或排查变更项,效率会高很多。

3. 第一层排查:CPU 与平均负载

3.1 先看平均负载,而不是直接看 CPU 使用率

很多人习惯用top里的%Cpu判断服务器是否吃紧,但平均负载(load average)是更值得先看的指标。平均负载代表单位时间内正在运行和不可中断的进程数量,它不只反映 CPU 使用,还包含处于 D 状态(不可中断睡眠)的进程。一个典型的场景是:磁盘 IO 出问题后,大量进程阻塞在 IO 等待上,平均负载飙升,但 CPU 使用率并不高。

执行uptime可以看到三组负载值,分别对应过去 1 分钟、5 分钟和 15 分钟的平均值。如果 1 分钟负载远高于 15 分钟负载,说明问题刚刚发生;如果三者都很高,说明问题已经持续一段时间。判断负载是否过高,不能只看绝对值,要结合 CPU 核心数。经验上,当平均负载持续超过核心数的 70% 到 80% 时,就需要开始排查了。比如 4 核服务器,负载持续高于 3 就要警惕。

3.2 定位消耗 CPU 的进程

确认负载过高后,下一步是找出到底是谁在消耗资源。top -c可以在进程列表里显示完整命令行,按大写P可以按照 CPU 使用率排序。为了看到更细粒度的数据,可以配合以下命令:

# 按 CPU 列出前 20 个进程 ps -eo pid,ppid,user,%cpu,%mem,cmd --sort=-%cpu | head -20 # 观察指定进程的 CPU 变化 pidstat -p <PID> 1 5

如果消耗 CPU 的是业务进程,需要进一步看是正常的流量增长还是代码死循环。如果是 Java 应用,可以使用top -Hp <PID>查看线程级 CPU 消耗,再用jstack导出线程栈来确定具体代码位置。如果是数据库,常见原因是缺少索引或 SQL 没有命中缓存。如果是突然多出来的陌生进程,则要立刻警惕安全问题,检查是否被入侵或者被恶意程序利用。

3.3 僵尸进程与不可中断进程

进程状态也很关键。ps -eo stat,pid,ppid,cmd | awk '$1 ~ /D|Z/'可以筛选出 D 状态和 Z 状态的进程。D 状态是不可中断睡眠,通常代表进程正在等待内核 IO 完成,大量 D 状态进程说明磁盘或网络 IO 存在严重阻塞。Z 状态是僵尸进程,代表子进程已结束但父进程没有调用 wait 回收,僵尸进程本身不占太多 CPU 和内存,但会占用 PID,大量累积会导致新进程无法创建。

遇到大量 D 状态进程,优先排查磁盘;遇到大量僵尸进程,优先排查父进程是什么,为什么没有正确回收子进程。对于使用 gunicorn、Supervisor 等进程管理工具的场景,还要确认进程管理器的配置是否正常,避免僵死子进程持续堆积。

4. 第二层排查:内存

4.1 free 输出里最容易误解的两个指标

内存排查中有一个高频误区:看到free -h里 used 很高就认为内存不足。实际上 Linux 会尽量利用空闲内存做缓存(cached/buffers),这部分内存在业务需要时可以释放。真正应该关注的是 available 字段,它表示在不触发交换的情况下,可供新进程使用的内存估计值。

运行free -h时,重点看 available 是否持续降低。如果 available 长时间接近 0,同时 swap 使用率上升,说明物理内存已经紧张,系统开始使用交换分区。磁盘交换会带来极大的性能抖动,从外部看就是服务时快时慢,非常符合“不稳定服务器”的特征。

4.2 OOM 发生时,系统的“遗言”在哪里

当内存真正耗尽时,Linux 内核的 OOM killer 会选中一个进程并杀掉它,以释放内存。被杀的进程不一定是内存占用最高的那个,具体的得分逻辑还涉及进程优先级、运行时长等因素,所以会有人遇到“明明另一个进程更占内存,却把 Java 服务杀了”的情况。

OOM 的痕迹不会出现在应用日志里,而会出现在内核日志中。排查命令如下:

# 查看最近的 OOM 记录 dmesg -T | grep -iE 'out of memory|killed process' # 使用 journalctl 查看内核日志 journalctl -k --since "2 hours ago" | grep -iE 'oom|killed process'

如果应用进程经常“意外消失”,登录服务器后第一件事就应该是执行这两条命令。看到Killed process 12345 (java)这样的记录,说明不是应用自身崩溃,而是操作系统主动杀掉了进程。根因通常不是“这次被杀”,而是内存为什么持续增长。

4.3 内存泄漏的初步定位思路

内存排查不能只停留在“内存不够就扩容”,很多情况下是程序存在内存泄漏。常见特征:内存使用随运行时间缓慢上涨,重启服务后明显回落,运行几天后又接近峰值。定位时先看哪个进程内存最大:

# 按物理内存占用列出前 10 个进程 ps -eo pid,ppid,user,rss,cmd --sort=-rss | head -10

如果是 Java 应用,可以用jmap -heap <PID>查看堆内存概况,也可以借助 Arthas、JProfiler 等工具分析堆转储文件。Python 应用可以结合 tracemalloc 或 objgraph 定位对象引用问题。如果是容器环境,别忘了看 cgroup 层面的限制,容器内即使 free 显示正常,也可能因为容器内存限制被 OOM 杀掉,这时的证据可能在dmesg中显示为Memory cgroup out of memory

5. 第三层排查:磁盘

5.1 不只是容量,还有 inode

服务器磁盘问题最容易理解,但也有一些隐蔽的坑。第一层是容量,df -h可以直观看到每个分区使用比例,当使用率达到 80% 以上时就要警惕。第二层是 inode,也就是文件系统索引节点数量。如果创建了海量小文件,比如临时文件、缓存文件、消息队列积压文件,磁盘容量可能还没满,inode 就已经耗尽,此时创建任何文件都会提示No space left on device

df -i可以查看 inode 使用率。如果 inode 使用率接近 100%,要立刻找出小文件最多的目录。可以通过下面脚本快速定位:

# 统计 /var 下各目录文件数量 for dir in /var /tmp /home /opt; do echo "$dir: $(find $dir -type f 2>/dev/null | wc -l)" done # 查看某个目录的 inode 消耗排行 du --inodes -x /var 2>/dev/null | sort -k1 -n | tail -20

注意,找到积压目录后不要贸然批量删除。一定要先确认这些文件属于哪个应用,是否还在被进程写。最安全的做法是先停止相关应用或确认文件无用,再做清理,清理前备份或至少将目录改名保留一段时间。

5.2 IO 延迟高和磁盘阵列异常

磁盘容量只是表面,真正影响稳定性的是 IO 延迟。使用iostat -x 1可以观察每秒的 IO 情况,重点关注%utilawait%util接近 100% 说明磁盘长期处于繁忙状态,await是 IO 请求的平均等待时间,数值越高代表响应越慢。

还有一种情况容易被忽略:磁盘阵列(RAID)中的一块硬盘故障,导致阵列进入降级状态。此时系统还能正常工作,但读写性能大幅下降,而且数据冗余度已经降低,存在数据丢失风险。对于硬件 RAID,建议定时查看阵列管理工具的状态;对于软件 RAID,可以使用以下命令查看:

# 查看软 RAID 状态 cat /proc/mdstat

如果阵列状态中出现degradedremoved[U_]之类的标记,说明有成员盘异常,需要尽快备份数据并更换故障盘。对于生产环境,磁盘阵列状态应该纳入日常监控和告警范围。

5.3 日志无限增长导致磁盘占满

日志是排查问题的重要依据,但日志本身也会成为“罪魁祸首”。很多服务器不稳定,就是/var/log目录被无限制增长的应用日志或容器日志塞满,最终导致磁盘爆掉,服务不断报错。

常见做法是配置 logrotate 对系统日志和应用日志做轮转。容器化环境则要限制 Docker 日志的大小,在/etc/docker/daemon.json中做如下配置:

{ "log-driver": "json-file", "log-opts": { "max-size": "100m", "max-file": "3" } }

这个配置表示单个容器日志文件最大 100MB,最多保留 3 个文件。配置修改后需要重启 Docker 守护进程才能生效,生产环境操作前要评估影响。除了日志,临时目录、上传目录、备份文件也是磁盘增长的常见来源,巡检时需要一并检查。

5.4 共用磁盘的应用互相影响

如果一个磁盘被多个应用共用,那么某个应用的突增写入会拖慢其他应用。比如数据库和 Web 应用放在同一块云盘上,当某条大 SQL 全表扫描导致磁盘 IO 飙高时,Web 应用读取静态文件同样会受影响,外部表现为接口变慢。如果条件允许,建议把日志目录、数据库数据目录、应用临时目录拆分到不同磁盘,从而隔离性能影响。

6. 第四层排查:网络

6.1 网络问题先分层,再定位

网络不稳定的表现很复杂,但排查时可以把问题拆成三层:链路通不通、端口通不通、服务进程响应是否正常。直接从现象出发,先跑几条基础命令:

# 测试到目标服务器的网络连通性 ping -c 5 <服务器IP> # 测试某个端口是否开放 telnet <服务器IP> <端口> # 查看本地监听的端口 ss -tlnp # 看一个接口的完整响应时间 curl -w "总耗时: %{time_total}\n 连接耗时: %{time_connect}\n" -o /dev/null http://127.0.0.1:8080/

如果 telnet 能通,但业务接口还是超时,问题大概率在服务进程本身或应用层依赖。如果 ping 不通,问题在链路或防火墙;如果 ping 通、telnet 不通,则要检查端口是否监听、防火墙规则是否允许访问。把问题限制在某个层面后,排查范围会小很多。

6.2 SSH 连接不稳定如何排查

“连接远程服务器总是断”“VSCode 连接 SSH 远程开发一会儿就掉线”是非常典型的不稳定表现。SSH 连接不稳定通常有以下几个原因:

  • 网络链路本身有丢包,可以使用ping -c 100 <IP> | grep loss看丢包率。
  • 服务器负载过高或 IO 阻塞,SSH 服务无法及时响应。
  • sshd 并发连接配置太低,导致新连接被拒绝。
  • 服务器开启了 DNS 反查,但内网 DNS 解析很慢。
  • 客户端网络环境切换频繁,连接存活时间太短。

针对 sshd 配置,可以在/etc/ssh/sshd_config中做以下优化:

# /etc/ssh/sshd_config 片段 UseDNS no GSSAPIAuthentication no # 提高并发连接与保持能力 MaxSessions 50 MaxStartups 30:50:100 ClientAliveInterval 60 ClientAliveCountMax 3

UseDNS no可以避免 SSH 登录时做反向 DNS 解析;ClientAliveInterval可以让服务端定期发送保活包,减少因网络空闲导致的断连。修改配置后,先用sshd -t检查语法,再执行systemctl reload sshd平滑生效。客户端排查时可以使用ssh -vvv user@host,观察连接卡在哪一步,如果是公钥认证阶段卡住,还要检查本地私钥和服务器authorized_keys的权限设置。

6.3 TCP 重传与连接堆积

网络不稳定还经常表现为 TCP 重传率升高。TCP 协议通过确认机制保证可靠传输,如果数据包在链路中丢失或延迟,发送方会重传。大量重传意味着链路质量差、带宽打满或中间设备出现丢包。

查看重传和连接状态可以使用以下命令:

# 查看 TCP 重传统计 netstat -s | grep -i 'retransmited' # 查看当前连接状态汇总 ss -s # 查看已建立连接数量 ss -tan state established | wc -l # 查看网卡丢包和错误统计 ethtool -S eth0 | grep -iE 'drop|err'

如果 established 连接数持续上涨,应用日志却没有明显报错,可能是连接池配置过大,或者有大量慢请求占着连接不放。此时可以结合ss -tan看连接对端 IP 分布,判断是否有异常访问或爬虫流量。生产环境建议对单 IP 并发连接数做限制,同时优化应用的连接池和超时时间。

6.4 DNS 与时间同步也会制造“假不稳定”

还有一种容易被误认为服务器不稳定的是 DNS 解析问题。接口调用依赖外部服务时,如果 DNS 解析经常超时,业务表现为偶发超时。排查时执行time nslookup <域名>,如果解析耗时忽高忽低,说明当前 DNS 服务器不稳定,可以更换为内网稳定的 DNS 或开启本地 DNS 缓存。

时间同步问题同样会表现出“不稳定”特征。比如定时任务在错误时间点启动,导致业务高峰被额外任务抢占资源;或者应用生成的 token 依赖时间戳,时间跳变后出现大量验签失败。前面讲的 chrony 配置就是为此准备的。

7. 虚拟化与云服务器场景

7.1 云服务器的“邻居干扰”

云服务器和物理服务器最大的区别,在于你使用的是宿主机上划分出来的虚拟资源。如果宿主机上的其他实例(业内常说的“邻居”)突发占用大量 CPU、磁盘 IO 或网络带宽,你的实例就会受到干扰。这种问题在共享型实例、免费云服务器或低配轻量应用服务器上更明显。

判断是否被“邻居干扰”,可以看 CPU 的 steal 指标。在top输出中,%st代表当前 CPU 被宿主机强制偷走的时间比例。如果%st长时间较高,说明宿主机资源竞争很激烈。云服务器场景下,如果业务逻辑没有明显变化,但性能突然波动,优先对比监控里的%st和带宽流量。如果确认邻居干扰严重,唯一有效的办法是迁移实例或升级到独享型规格,单纯重启解决不了问题。

7.2 突发 CPU 与带宽基线

不少云服务器是突发型实例,正常情况下允许短时间跑满 CPU,但如果持续满负荷运行,会被限流到基准性能附近。这会带来一种很有迷惑性的现象:刚买来或刚重装系统时性能很好,跑一段时间后突然变慢,重启后又恢复。原因就是重启后 CPU 积分或突发额度被重新计算。

面对这种情况,不要盲目在系统层反复调参,应该先到云控制台查看实例规格、CPU 突发额度和带宽基线。如果业务需要长期稳定运行,应该选择性能型实例,或者对任务进行削峰填谷,避免长时间满跑。

7.3 虚拟机、容器与裸金属的排查层级差异

不同虚拟化技术下,你能看到的系统指标含义并不相同。物理机或裸金属上,freetopiostat看到的都是真实硬件资源。KVM 虚拟机里,部分指标是宿主机虚拟出来的,CPU 型号和核数通常与实际一致,但性能仍受宿主机调度影响。Docker 容器内执行topfree,看到的是宿主机的内核视角,不一定反映容器真实使用量,更准确的应该使用docker stats查看容器资源占用。

如果容器应用表现为不稳定,优先检查容器是否接近 cgroup 限制,例如内存达到 limit 后会被频繁 OOM,CPU 达到 quota 后会被 throttle。宿主机上的其他容器也可能抢占资源。排查容器问题时,需要同时查看宿主机指标和容器指标,不能只看其中一层。

8. 常见不稳定根因与修复对照表

问题现象常见根因快速确认命令处理思路
接口偶发超时,CPU 不高宿主机 CPU steal 高或磁盘 IO 阻塞uptime/top 看%st,iostat 看%util迁移实例,拆分磁盘,排查热点进程
内存持续上涨后进程被杀应用内存泄漏或容器内存限制过小dmesg -T 查 OOM,docker stats 查容器内存修复泄漏,调整 JVM 堆或容器内存 limit
磁盘容量没满但创建文件失败inode 被小文件耗尽df -i清理小文件,调整日志轮转策略
磁盘写入很慢,服务整体卡顿磁盘 IO 打满或软 RAID 降级iostat -x 1,cat /proc/mdstat定位写入进程,检查阵列状态,扩容或更换磁盘
SSH 连接经常断开网络丢包、sshd 并发限制、DNS 反查慢ping 查丢包,ssh -vvv 看阶段优化 sshd_config,检查客户端网络
服务偶发无响应,重启后恢复资源耗尽后进程被系统杀掉journalctl -k 查 OOM按第 3-5 节方法与顺序定位资源瓶颈
日志时间线和实际不一致NTP 未配置或校时端口不通chronyc sources -v配置 chrony,开放 UDP 123 端口
TCP 重传多,客户端频繁超时链路丢包、带宽打满、防火墙限流netstat -s 查重传,ethtool -S 查网卡联系网络服务商,调整 QoS 和限流

这个表只覆盖了最常遇到的几个场景。实际生产中,问题可能是多个根因叠加引起的,比如内存泄漏导致服务变慢,服务变慢导致线程堆积,线程堆积导致 CPU 升高,最终整个链路雪崩。所以排查时要保持“先止损、后定位”的思路,而不是试图一次找到所有原因。

9. 生产环境稳定性治理最佳实践

9.1 先止损,再排查

生产环境出现不稳定时,第一目标不是立刻找出根因,而是恢复业务。盲目在一台快挂掉的服务器上执行各种排查命令,不仅危险,还可能加剧问题。合理顺序是:先确认业务影响范围,然后根据情况选择重启单实例、切换流量、扩容新实例或回滚最近变更,待业务稳定后再回头分析根因。

重启有讲究,不建议在同一时间把所有实例全部重启,应该采用滚动重启,每次只重启一部分,观察业务是否恢复再做下一步。如果怀疑是最近发布导致的问题,优先回滚而不是继续调优。止损和排查可以并行,但止损永远拥有更高优先级。

9.2 自动化巡检与告警

服务器不稳定很多情况下是可以提前发现的。以最开始提供的server_check.sh为例,可以把它加入 crontab,定期执行并留档:

# 每 5 分钟执行一次,日志保留在 /var/log 目录 */5 * * * * /usr/local/bin/server_check.sh >> /var/log/server_check.log 2>&1

但巡检脚本只能提供快照,真正的稳定性治理需要持续监控和告警。建议至少覆盖以下指标:CPU 使用率、平均负载、内存 available、磁盘使用率、inode 使用率、磁盘 IO 延迟、网络丢包率、TCP 重传率、进程存活状态。监控不是为了在故障后看回放,而是为了在故障前收到告警。对于个人项目,可以先用简单的 shell 脚本加邮件通知;对于团队项目,建议搭建完善的监控告警体系。

9.3 容量规划与架构冗余

稳定性不只是排查问题,更是提前避免问题。容量规划的关键是给关键资源留足余量,通常建议 CPU、内存、磁盘使用率达到 60% 到 70% 时就考虑扩容或清理,而不是等到 90% 再处理。带宽和连接数也要做容量评估,业务增长时及时扩容。

架构层面,尽量消除单点。使用负载均衡对外提供服务,数据库做主从或高可用集群,缓存和消息队列做集群部署。需要考虑的一个问题是:引入集群后虽然提升了可用性,但也引入了新的不稳定因素,比如集群节点时钟不同步、脑裂、配置不一致等。架构越复杂,对监控和变更管理的要求就越高。

对于 Web 服务器安全,不要只关注性能。定期更新系统补丁,关闭不必要的服务端口,限制 SSH root 远程登录,使用密钥认证代替密码登录,配置防火墙最小开放原则,这些都属于稳定性的基础工程。安全事件是造成服务器不稳定的一个非常常见的诱因,被植入挖矿程序后,CPU 经常飙到 100%,这种不稳定不是资源规划能解决的。

GPU 服务器是另一个需要单独关注的方向。训练任务表现不稳定时,除了常规的 CPU、内存、磁盘,还要关注 GPU 温度和显存占用。执行nvidia-smi可以看到 GPU 利用率、显存、温度、风扇转速,以及 ECC 错误计数。如果 ECC 错误持续增长,说明 GPU 硬件可能存在问题。多卡训练还要检查 NVLink 或 PCIe 链路状态。GPU 服务器的运维重点在于驱动版本、CUDA 版本、显存清理和温度控制,这些内容值得单独写一篇文章。

9.4 变更管理与可观测性

最后强调两点:第一,所有变更必须可回溯;第二,所有关键路径必须可观测。可回溯意味着你能回答“这台服务器的配置昨天是什么样,今天改了什么,为什么改”。可观测意味着当链路某个环节变慢时,你能快速判断是应用问题、数据库问题还是基础设施问题。

对个人开发者来说,即使没有团队,也建议养成写变更日志的习惯。很多“莫名其妙”的不稳定,在记录变更之后都会变得“有迹可循”。对团队来说,则要建设好日志聚合、链路追踪和监控告警三条核心能力。这类基础设施建设看起来投入大,但每一次故障排查中节省的时间,都会成倍回报回来。

排查不稳定服务器的方法到这里已经完整串联起来了:从准备监控和时间同步开始,依次检查 CPU 和负载、内存与 OOM、磁盘容量与 IO、网络与连接,再结合虚拟化和云服务器的特殊场景,最后用变更记录和容量规划来防止问题复现。与其收藏这篇文章,不如先把文中那个简易巡检脚本放到服务器上跑一次,等下次服务器再次露出“不稳定的统治”苗头时,你至少已经有了可以按顺序出牌的底牌。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/8 8:27:54

测试用例设计与编写实战:方法、模板与优先级管理

测试用例这东西&#xff0c;说实话&#xff0c;看着简单&#xff0c;写好不容易。我在测试这行摸爬滚打了这么多年&#xff0c;见过太多“看起来行云流水、一执行就翻车”的项目&#xff0c;根源往往不是执行的人不行&#xff0c;而是用例本身就没写好。所以今天这篇&#xff0…

作者头像 李华
网站建设 2026/9/8 8:27:54

Go并发编程实战:从goroutine、channel到GMP模型与性能调优

1. 为什么咱们都该好好学学Go的并发干咱们这行的&#xff0c;迟早会碰到并发这道坎。Java里有线程池&#xff0c;Python里有GIL&#xff0c;C里有各种锁和原子操作&#xff0c;轮子不少&#xff0c;但真正想把并发写得又简单又不容易出错&#xff0c;Go绝对是绕不开的那一个。我…

作者头像 李华
网站建设 2026/9/8 8:27:32

从 LangChain 到 LangGraph:Agent 开发如何走向工程化与状态可控

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/8 8:26:37

分治算法求解最大子数组和:MaxSubSum 递归实现详解

在刷题和做算法设计的时候&#xff0c;最大子数组和问题&#xff08;Maximum Subarray Sum&#xff09;几乎是绕不开的一道坎。LeetCode 上有它的经典版本&#xff08;53 题&#xff09;&#xff0c;各大教材里它又是分治策略和动态规划的必讲例题。很多人一看到这个题&#xf…

作者头像 李华
网站建设 2026/9/8 8:26:35

用AI写专利的实战方法论:通用大模型+提示词+检索工具组合方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/8 8:26:06

.NET Core跨平台调用SAP RFC完整指南:从NCo配置到Linux部署

简介&#xff1a;面向 .NET Core 项目调用 SAP RFC 接口的完整 SDK 组件包&#xff0c;适配 Windows 与 Linux 双平台&#xff0c;主要服务于需要对接 SAP 系统的 .NET Core 后端开发人员。包内包含开发所需的头文件&#xff08;h/c/cpp&#xff09;、动态与静态库&#xff08;…

作者头像 李华