Linux 服务器运维实战:从选型到故障排查全攻略 - 夜莺博客

Linux 服务器运维实战:从选型到故障排查全攻略

Linux 服务器承载着企业核心业务,稳定性和性能直接决定应用质量,而"从选型到故障排查"的完整能力正是运维工程师的核心竞争力。发行版选错了后期维护成本翻倍,参数调优没有数据支撑就是瞎调,故障排查没有流程就是救火。本文系统梳理 Linux 服务器运维全流程:发行版选择、性能优化、安全加固、监控告警与故障排查,帮助运维人员真正掌控自己的服务器。

发行版选择

生产环境稳定性第一:RHEL 及免费衍生版 Rocky Linux、AlmaLinux 适合长期支持和大规模部署;Ubuntu Server LTS 社区资源丰富、软件更新频繁,适合开发测试和云原生场景(Docker/K8s);Debian 资源占用极低、稳定版几乎没有 bug,适合轻量场景。没有最好的发行版,只有最匹配业务需求的发行版。

发行版 支持周期 适合场景 需要注意
RHEL / Rocky / AlmaLinux 约 10 年 企业核心业务、等保合规、需要长期不升级 软件包版本偏旧,新特性要依赖 EPEL 或容器
Ubuntu Server LTS 5 年(可扩展) 云原生、容器宿主、开发测试 两年一次大版本,需规划升级窗口
Debian 稳定版 约 5 年 轻量服务、内网工具、资源受限环境 软件包更新保守,新内核需自行引入

选型时把三个变量写清楚:支持周期、内核与软件包版本、团队熟悉度。服务器的生命周期通常按四年以上规划,因此"这个版本还能拿几年安全补丁"往往比"这个版本有什么新功能"更有决定意义。落地前先确认环境事实,不要凭记忆实施:

cat /etc/os-release            # 发行版与版本号
uname -r                       # 内核版本,决定支持哪些新特性
systemd-detect-virt            # 物理机还是虚拟机/容器
free -h; df -hT                # 内存与文件系统基线
rpm -qa | wc -l                # 已装软件包数量,越小攻击面越小(Debian 系用 dpkg -l)

新上线服务器建议只装最小化系统,把业务运行环境用配置管理工具补齐,而不是从"装了所有工具的模板机"克隆 —— 模板机是技术债最常见的来源。

系统初始化与基线配置

统一的基线配置决定了后续排障效率。时间、日志、资源限制这三件事如果不做,出故障时会先花两小时在核对时间戳上。

# 1. 时间同步:时间不准会让日志比对和证书校验全部失效
timedatectl set-timezone Asia/Shanghai
timedatectl set-ntp true
chronyc sources -v
chronyc tracking

# 2. 日志持久化(默认重启后 /var/log/journal 可能丢失)
mkdir -p /var/log/journal && systemd-journald --flush
# /etc/systemd/journald.conf: Storage=persistent, SystemMaxUse=2G

# 3. 资源限制:高并发应用的文件描述符永远不够用
# /etc/security/limits.conf
* soft nofile 65535
* hard nofile 65535
# /etc/sysctl.conf
fs.file-max = 2000000

ulimit -n; sysctl fs.file-max   # 确认生效

基线还包括主机名与 DNS 规范(hostnamectl set-hostname app-01.example.com)、SELinux 状态确认(getenforce,生产环境建议保持 Enforcing 而不是直接关闭),以及一份"开机自启服务清单":用 systemctl list-unit-files --state=enabled 核对并关掉不需要的服务——这是最小化攻击面最省力的一步。

性能优化要点

# 观察 CPU:wa 高说明磁盘是瓶颈,sy 高检查系统调用
top / htop
# 减少内存交换,让活跃进程驻留物理内存
vm.swappiness = 10~20   # /etc/sysctl.conf
# 磁盘 IO:频繁读写的目录挂独立 SSD 分区,加 noatime
# 网络高并发
net.core.somaxconn
net.ipv4.tcp_tw_reuse

每一次参数调优都应在测试环境验证后再上线,用 iostat、perf 定位瓶颈,而不是凭感觉改参数。

调优的顺序是先建立基线,再定位瓶颈,最后改一个参数并复测。没有基线数据,任何"优化"都无法证明确实有效。四个维度各有对应的观察工具:

# CPU:谁在消耗,上下文切换是否异常
mpstat -P ALL 1 5
pidstat -u -w -p ALL 1 5
perf top

# 内存:可用内存、缓存命中、是否在换页
vmstat 1 5
sar -r 1 5
cat /proc/meminfo | grep -E 'MemAvailable|Dirty|Writeback'

# 磁盘:await 与 %util 是判断饱和度的关键
iostat -xz 1 5
iotop -o
# 常用 sysctl 项
vm.dirty_ratio = 10
vm.dirty_background_ratio = 5
vm.vfs_cache_pressure = 50

# 网络:队列溢出与连接数
ss -s
sar -n DEV,TCP,ETCP 1 5
ethtool -S eth0 | grep -i drop
net.core.somaxconn = 32768
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.tcp_tw_reuse = 1

几个容易被忽略但收益明显的点:把日志目录、数据目录分开挂载,避免日志写满拖垮数据库;挂载选项加 noatime 减少无意义的元数据写;把 vm.dirty_ratio 调低可以避免大流量写入时出现秒级 IO 停顿;数据库类服务的 IO 调度器用 none(NVMe)或 mq-deadline,而不是默认值。

磁盘与容量管理

磁盘满是最常见的生产事故之一,而它几乎总是"渐进发生"的,所以告警阈值比清理技巧更重要。

# 快速定位占满的目录
df -hT; df -i                       # -i 看 inode,数量型业务常被 inode 撑满
du -sh /* 2>/dev/null | sort -rh | head -20
du -xhd1 /var 2>/dev/null | sort -rh

# 已删除但仍被进程占用的文件(du 和 df 不一致时的元凶)
lsof +L1 | sort -k7 -rn | head -20

# 日志轮转与 journal 清理
logrotate -d /etc/logrotate.conf    # 先 dry-run 看配置是否正确
journalctl --vacuum-size=500M
journalctl --vacuum-time=7d

# LVM 在线扩容(多数生产盘都留了余量)
vgs; lvs
lvextend -L +20G /dev/vg0/root
xfs_growfs /          # ext4 用 resize2fs -p /dev/vg0/root

容量管理的原则是:任何增长型目录都必须有轮转策略和独立分区,/var/log、/var/lib/docker、/tmp 和数据库数据目录是最常出事的四类。阈值按级别设置:75% 提醒、85% 处理、92% 立即介入;inode 使用率单独告警,因为它耗尽时 df -h 看起来一切正常,写入却全部失败。

安全加固基线

  • 修改 SSH 默认配置:PermitRootLogin no、更改监听端口、PasswordAuthentication no 仅密钥认证。
  • 安装 fail2ban 自动拦截多次失败 IP。
  • 用 iptables/firewalld 只开放必要端口(80、443、22 等)。
  • 敏感目录启用 SELinux 或 AppArmor,进程被攻破也无法越权读取 /etc/shadow。

SSH 是最大的暴露面,也是加固收益最高的地方。/etc/ssh/sshd_config.d/99-hardening.conf 建议至少包含:

Port 22
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
PermitEmptyPasswords no
MaxAuthTries 3
MaxSessions 4
ClientAliveInterval 300
ClientAliveCountMax 2
AllowUsers deploy ops
X11Forwarding no
AllowTcpForwarding no
LoginGraceTime 20

# 改完先语法检查再重启,避免把自己锁在外面
sshd -t && systemctl reload sshd

其余加固项按优先级排列:用 firewalld/iptables 默认拒绝入站,只放行必要端口;把 SSH 端口暴露给跳板机而不是全网;开启自动安全更新(RHEL 系 dnf-automatic,Debian 系 unattended-upgrades),内核漏洞的修复窗口通常只有几天;启用 auditd 记录关键文件变更(/etc/passwd、/etc/sudoers、SSH 密钥目录)。

监控与告警

用 htop 交互查看进程资源、nmon 记录历史性能、iftop 实时查看带宽。建议每天用 cron 检查磁盘剩余空间、内存剩余量和服务存活状态,异常立即告警。监控不是事后补救,而是提前预防。

单机脚本巡检适合没有监控系统的环境,而实际生产中更推荐 node_exporter + Prometheus + Alertmanager 的组合,把采集、存储、告警和通知分开。指标不必多,但下面这几个必须告警:

# node_exporter 关键告警表达式示例
node_load5 / count(node_cpu_seconds_total{mode="idle"}) > 1.5     # 5 分钟负载 > 1.5 倍核数
node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes < 0.10
(node_filesystem_avail_bytes / node_filesystem_size_bytes) < 0.15  # 使用率 > 85%
node_filesystem_files_free / node_filesystem_files < 0.15          # inode 告警
up{job="node"} == 0                                                # 实例失联

备份与恢复演练

没有演练过的备份等于没有备份。备份策略建议遵循 3-2-1:至少三份副本、两种介质、一份异地。服务器配置本身也应该版本化 —— /etc 纳入 Git,变更走评审,这样新机器上线或灾难恢复时不必凭记忆重建。

etckeeper init && etckeeper commit "initial state"   # /etc 纳入 Git
rsync -aHAX --delete /srv/data/ backup@10.10.0.9:/backup/srv-data/  # 增量异地副本
tar -tzf /backup/2026-09-01-etc.tar.gz | head        # 验证可恢复性,而非只看体积

恢复演练的频率建议:核心业务每季度一次,非核心每半年一次,并且记录恢复耗时(RTO)和数据丢失量(RPO)。演练发现的问题才是备份方案真正的价值所在。

故障排查标准路径

uptime              # 负载,超过核心数2倍说明过载
dmesg -T | tail -20 # 内核报错:OOM killer、磁盘坏道
journalctl -xe      # 应用报错(如 Nginx 502 常见 php-fpm 挂掉)
strace -p [PID]     # 跟踪进程卡在哪个 IO/网络操作
lsof -i :80         # 端口占用
du -sh /* | sort -rh  # 磁盘满定位
ps aux --sort=-%mem   # 内存泄漏排查

排查的核心是"按层收敛",从下往上逐层排除:硬件与内核 → 资源(CPU/内存/磁盘/网络)→ 系统服务 → 应用进程。上层现象往往由下层引起,跳过下层直接改配置是最常见的错误。

现象 首选命令 常见根因
服务响应慢、无报错 vmstat 1、iostat -xz 1 磁盘 await 飙升、内存换页(si/so 非 0)
SSH 能连上但登录缓慢 getent hosts <hostname> DNS 反向解析超时、UseDNS yes
进程被随机杀掉 dmesg -T | grep -i oom OOM Killer 触发,需限制应用内存或加 swap
日志报 "No space left" df -i、lsof +L1 inode 耗尽,或已删除文件仍被进程持有

关于 load average 需要补充一句:它统计的是运行队列和不可中断睡眠(IO 等待)的进程数,因此高负载不一定代表 CPU 忙,也可能是磁盘在拖后腿。用 vmstat 的 r 列和 b 列区分这两种情况,再决定优化 CPU 还是存储。

自动化与变更管理

重复的手工操作是事故的主要来源:把日常动作固化成脚本或交给配置管理工具,并保证每一步都可回滚。

tar -czf /backup/pre-change-$(date +%F-%H%M).tar.gz /etc /srv/app/config   # 变更前快照
ansible all -i inventory -m lineinfile \
  -a "path=/etc/ssh/sshd_config regexp='^PermitRootLogin' line='PermitRootLogin no'"
ansible-playbook -i inventory site.yml --limit app-01      # 灰度:先 1 台
ansible-playbook -i inventory rollback.yml --limit app-01  # 回滚脚本须演练过

变更管理的三条底线:任何变更都留书面记录(改了什么、为什么、怎么回滚);生产变更避开业务高峰并有人在岗;监控指标在变更后立刻复核,而不是等用户报障。做到这三点,故障定位时间通常能从小时级降到分钟级。

结合 Linux 性能排障指南、Linux 运维 33 个排障技巧、Chrony 时间同步排障 和 smartctl 磁盘健康监控 可以搭建完整的 Linux 运维知识体系。

原文链接:https://www.linuxcool.com/linux%E7%B3%BB%E7%BB%9F%E6%9C%8D%E5%8A%A1%E5%99%A8%E8%BF%90%E7%BB%B4%E5%AE%9E%E6%88%98-%E4%BB%8E%E9%80%89%E5%9E%8B%E5%88%B0%E6%95%85%E9%9A%9C%E6%8E%92%E6%9F%A5%E5%85%A8%E6%94%BB%E7%95%A5