Ubuntu服务器突然变慢,第一个要查的就是慢查询日志。MySQL和PostgreSQL都有内置的慢日志功能,定位到具体哪条SQL语句拖了后腿,优化就成功了一半。对于MySQL,编辑配置文件/etc/mysql/mysql.conf.d/mysqld.cnf,找到并修改以下几行:

slow_query_log = 1
slow_query_log_file = /var/log/mysql/mysql-slow.log
long_query_time = 2

这里将long_query_time设置为2秒,意味着执行时间超过2秒的查询都会被记录。修改后重启MySQL服务:sudo systemctl restart mysql。然后使用mysqldumpslow工具分析慢日志:sudo mysqldumpslow /var/log/mysql/mysql-slow.log,它会汇总显示最耗时的查询模式。

如果是PostgreSQL,需要调整postgresql.conf中的参数:

logging_collector = on
log_destination = 'stderr'
log_directory = 'pg_log'
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'
log_min_duration_statement = 2000

log_min_duration_statement设为2000毫秒,重启服务后,执行时间超过2秒的语句会记录在pg_log目录下的日志中。进一步分析可以使用pg_stat_statements扩展,它能统计所有SQL的执行时间和调用次数。

系统资源瓶颈的快速定位:iostat、vmstat与top组合拳

慢日志指向数据库问题,但有时瓶颈在系统IO或内存。这时需要一套组合命令。先用top看整体,按‘1’展开所有CPU核心,观察%wa(IO等待)指标,如果持续过高,说明磁盘IO是瓶颈。接着用iostat -x 2查看详细磁盘状态,关键列是%util(设备利用率)和await(平均等待时间),如果%util接近100%,说明磁盘已经满负荷。

内存方面,vmstat 2命令每隔2秒输出一次系统状态。重点关注si(从磁盘交换进内存)和so(从内存交换到磁盘)两列,如果它们经常非零,说明发生了交换(swap),物理内存不足,这会严重拖慢性能。此时需要检查哪些进程占用内存最多,可以使用ps aux --sort=-%mem | head -10列出前10名。

失控进程的精准识别与处理:kill、pkill与cgroup限制

找到问题进程后,处理要分步骤。先用kill -15 PID发送SIGTERM信号,允许进程进行清理工作后正常退出。如果无响应,再使用kill -9 PID强制终止。对于只知道进程名的情况,pkill -f “进程名模式”非常有用。但强制终止是最后手段,可能引发数据丢失。

更高级的做法是使用cgroups(控制组)来限制进程的资源占用,防止单个进程拖垮整个系统。例如,创建一个名为limit_mem的cgroup来限制内存使用:

sudo cgcreate -g memory:limit_mem
sudo cgset -r memory.limit_in_bytes=500M limit_mem

然后将目标进程的PID加入这个组:sudo cgclassify -g memory:limit_mem PID。这样,该进程最多只能使用500MB内存,超限会被内核终止,避免了系统级崩溃。

网络连接数暴涨与TIME_WAIT堆积的解决

Web服务器如Nginx/Apache突然响应变慢,可能是网络连接数达到上限。用ss -s查看总连接数统计,用netstat -an | grep :80 | wc -l统计特定端口连接。如果TIME_WAIT状态连接过多,会快速耗尽可用端口。临时调整内核参数可以加速回收:

sudo sysctl -w net.ipv4.tcp_tw_reuse=1
sudo sysctl -w net.ipv4.tcp_fin_timeout=30

第一个参数允许重用TIME_WAIT状态的连接,第二个将FIN等待超时从默认的60秒减到30秒。要使配置永久生效,需要将这两行添加到/etc/sysctl.conf文件末尾,然后执行sudo sysctl -p

日志文件膨胀的实时监控与自动轮转

应用程序日志(如Nginx的access.log)或系统日志(syslog)不加管理会撑爆磁盘。使用logrotate工具是标准做法。编辑配置文件/etc/logrotate.d/nginx(示例):

/var/log/nginx/*.log {
    daily
    missingok
    rotate 14
    compress
    delaycompress
    notifempty
    create 0640 www-data adm
    sharedscripts
    postrotate
        invoke-rc.d nginx rotate > /dev/null
    endscript
}

这个配置表示:每天轮转一次,保留最近14天的日志,启用gzip压缩,轮转后创建新日志文件并设置权限。对于实时监控磁盘使用,可以设置一个简单的cron任务,每小时检查一次:df -h | grep -E ‘^/dev’ | awk ‘{if ($5 > “80%”) print $1 “ is “ $5}’,当磁盘使用超过80%时发出警告。

系统级性能剖析:perf与SystemTap实战

当常规工具无法定位深层次性能问题时,需要内核级剖析工具。perf是Linux内核内置的性能分析工具。安装:sudo apt install linux-tools-generic。常用命令如sudo perf top实时查看函数级CPU占用,sudo perf record -g -p PID记录特定进程的调用栈,然后用sudo perf report生成可视化报告。

对于更复杂的跟踪,比如追踪文件IO延迟或调度器行为,可以使用SystemTap。先安装:sudo apt install systemtap。一个简单的脚本,统计进程调用read系统调用的次数:

probe syscall.read {
    if (pid() == target())
        printf("PID %d called read\n", pid())
}

保存为test.stp,然后用sudo stap test.stp -x PID运行。这些工具提供了从用户态到内核态的完整视角,是解决疑难杂症的终极武器。

预防优于治疗:构建常态化监控与自动化响应

故障排查终究是被动的,主动监控才能防患于未然。部署一个轻量级的监控组合:Prometheus负责指标收集,Node Exporter暴露系统指标,Grafana进行可视化。关键指标包括:CPU负载(1分钟、5分钟、15分钟)、内存可用率、磁盘IOPS、网络带宽使用率。为这些指标设置告警规则,当CPU负载持续5分钟超过核心数的80%,或内存可用率低于10%时,自动触发告警。

更进一步,可以编写自动化处理脚本。例如,当检测到某个服务进程内存泄漏导致占用超过阈值时,脚本自动重启该服务并发送详细报告。或者,当Web服务器连接数异常飙升时,自动触发限流规则。将日常排查经验固化为自动化脚本,是运维从救火到防火的关键跃升。

Ubuntu运维的高效故障排查,是一个从表象(系统变慢)到根源(具体进程、SQL、配置)的拆解过程。熟练掌握从慢日志分析、系统命令组合到内核工具链的使用,并建立主动监控体系,才能确保服务持续稳定。记住,每一次故障的解决,都应该沉淀为一条监控规则或一个自动化脚本,这样系统才会越运维越健壮。