CentOS 7.6 这种“老古董”系统,持续开机几个月后变卡,这其实是 Linux 运维中非常经典的一个现象。别急着重装系统,大多数情况下不是硬件坏了,而是资源管理或软件层面的“慢性中毒”。
我们可以从以下几个最核心的维度来排查和解决:
1. Swap 交换分区与内存压力(最常见原因)
CentOS 7 默认开启 Swappiness(通常值为 60)。当物理内存(RAM)快用完时,内核会频繁地将不常用的内存页置换到磁盘上的 Swap 分区。
- 现象:服务器负载(Load Average)可能不高,但 I/O Wait(iowait)飙升,CPU 使用率看似正常,但响应极慢。
- 原因:机械硬盘或低速 SSD 作为 Swap 介质时,随机读写性能极差。如果业务有内存泄漏或者突发流量导致内存耗尽,系统会在 RAM 和 Swap 之间反复颠簸(Thrashing),导致 CPU 大部分时间都在等待磁盘 I/O。
- 验证方法:
free -h vmstat 1 5 # 观察 si (swap in) 和 so (swap out) 列是否有大量数据流动 - 解决方案:
- 短期:重启服务释放内存。
- 长期:检查是否有进程内存泄漏(用
top或htop按M键排序看谁占内存最多)。适当增加 Swap 大小(虽然治标不治本,但能避免 OOM Kill),或者优化应用代码减少内存占用。 - 参数调整:可以尝试将
vm.swappiness调低(如设为 10 或 1),让内核更倾向于保留物理内存,而不是轻易使用 Swap。sysctl vm.swappiness=10
2. 文件句柄与进程数限制
Linux 对每个用户和系统总的文件描述符(file descriptors)是有上限的。
- 现象:新连接无法建立,数据库报错 Too many open files,Nginx/Apache 拒绝服务。
- 原因:某些 Java 应用、Python 脚本或自定义服务如果没有正确关闭连接或文件句柄,会造成“句柄泄漏”。几个月下来,累积的未关闭句柄可能触发了系统的
fs.file-max限制。 - 验证方法:
cat /proc/sys/fs/file-nr ulimit -n lsof | wc -l # 查看当前打开的文件总数 - 解决方案:
- 修改
/etc/security/limits.conf,提高nofile限制。 - 检查并修复应用程序中的资源泄露问题。
- 修改
3. 日志爆炸与磁盘空间碎片化
- 现象:
df -h显示磁盘空间不足,或者du -sh /*发现某个目录(通常是/var/log)异常巨大。 - 原因:
- 日志未轮转:某些应用没有配置 logrotate,导致单个日志文件无限增长,塞满磁盘。
- 僵尸进程/孤儿进程:虽然不直接占磁盘,但如果伴随大量错误日志输出,会迅速消耗磁盘空间和 I/O 带宽。
- Inode 耗尽:如果目录下有数百万个小文件(如缓存、会话文件),即使磁盘容量没满,也可能因为 Inode 用完而无法创建新文件。
- 验证方法:
df -i # 检查 Inode 使用情况 du -sh /var/log/* | sort -hr # 找出最大的日志文件 - 解决方案:
- 清理或归档旧日志。
- 配置
logrotate自动切割和压缩日志。 - 如果是 Inode 耗尽,需要删除大量小文件或扩容文件系统(Ext4 支持在线扩容 Inode,但需谨慎操作)。
4. 定时任务(Cron)堆积或冲突
- 现象:CPU 突然飙高,然后慢慢恢复,周期性出现。
- 原因:
- 某个 Cron 任务执行时间过长,覆盖了下一个周期的开始时间,导致多个实例并行运行,资源竞争加剧。
- 某些备份脚本、监控脚本在深夜集中运行,如果脚本写得不好(比如全表扫描、大文件拷贝),会拖垮整个系统。
- 验证方法:
crontab -l ls -lt /var/spool/cron/ # 结合 lastcomm 或 auditd 查看历史命令执行情况 - 解决方案:
- 优化 Cron 任务的执行逻辑,添加锁机制(如
flock)防止并发。 - 将高负载任务错峰执行。
- 优化 Cron 任务的执行逻辑,添加锁机制(如
5. 内核参数与网络栈积压
- 现象:网络连接不稳定,TCP 连接建立缓慢,丢包率高。
- 原因:
- TCP TIME_WAIT 过多:高并发短连接场景下,大量连接处于 TIME_WAIT 状态,占用端口和资源。
- Netfilter/IPTables 规则复杂:如果防火墙规则非常多且复杂,每次数据包都要经过长长的规则链匹配,CPU 开销巨大。
- 中断平衡(IRQ Balance):多核服务器上,如果网卡中断只集中在一个 CPU 核心上,会导致单核满载而其他核心空闲。
- 验证方法:
ss -s # 查看 TCP 连接状态统计 iptables -L -n --line-numbers # 检查规则数量和复杂度 cat /proc/interrupts | grep eth0 # 查看网卡中断分布 - 解决方案:
- 调整 TCP 内核参数(如
tcp_tw_reuse,tcp_fin_timeout)。 - 精简防火墙规则,或使用 nftables/firewalld 的规则优化。
- 确保
irqbalance服务正在运行,使中断均匀分布在各个 CPU 核心上。
- 调整 TCP 内核参数(如
6. CentOS 7.6 自身的已知问题
- 内核版本较老:CentOS 7.6 使用的是 3.10.x 内核,这个内核在处理现代高并发、NUMA 架构、以及某些新型存储驱动时效率不如后续版本(如 4.19+ 或 5.10+)。
- SELinux 干扰:如果 SELinux 处于 Enforcing 模式,且应用权限设置不当,会导致大量的 AVC 拒绝记录,不仅影响性能,还会产生海量审计日志。
- 验证方法:
getenforce ausearch -m avc -ts recent # 查看最近的 SELinux 拒绝记录 - 解决方案:
- 如果确认应用兼容,可以将 SELinux 设置为 Permissive 模式测试性能提升。
- 考虑迁移到 AlmaLinux/Rocky Linux 8/9 或 Ubuntu LTS,获得更新的内核和安全补丁。
总结建议
- 第一步:登录服务器,运行
top和vmstat 1 5,确定是 CPU、内存还是 I/O 瓶颈。 - 第二步:如果是 I/O 瓶颈,重点查 Swap 和日志;如果是 CPU 瓶颈,查 Cron 任务和特定进程。
- 第三步:检查
dmesg和/var/log/messages,看是否有硬件错误或内核警告。 - 长期策略:CentOS 7 已于 2024 年 6 月停止维护(EOL),强烈建议规划迁移至受支持的操作系统。对于生产环境,定期重启(如每月一次)也是一种简单有效的“清理”手段,但这不应成为常态。
记住,Linux 不像 Windows 那样需要频繁重启来“清理”,它的设计哲学是稳定运行数年。如果出现变卡,一定是某个环节出现了资源泄漏或配置不当,找到那个“漏水的桶”比换掉整个水箱更重要。
云技术博客