Ubuntu服务器在长期运行中,最让人头疼的不是初始搭建,而是半夜突然宕机、服务无响应或者CPU莫名飙到100%。面对这种问题,直接登录服务器,第一时间不是重启,而是通过日志锁定根因。重启虽然能暂时恢复,但会破坏现场,让问题变成悬案。日志就是服务器运行的黑匣子,掌握正确的排查方法,能让你在几分钟内从海量信息中精准揪出故障点。
系统日志的核心入口:journalctl在Ubuntu 16.04及之后的版本中,systemd-journald已经成为日志管理的核心。它把内核消息、服务启动日志、系统应用输出全部集中管理,并且自带二进制存储和轮转功能。排查问题的第一步,就是用好journalctl命令。
查看本次启动后的所有日志,直接使用:
journalctl -b
这个命令输出量极大,需要配合过滤。如果想看上一次启动的日志,也就是系统崩溃重启之前的关键信息,用:
journalctl -b -1
这是排查突然宕机问题的核心命令。很多运维人员习惯用/var/log/syslog,但syslog是文本文件,系统崩溃时最后几条关键日志可能因为磁盘缓存没刷盘而丢失。journalctl的二进制日志写入机制更可靠,能保留更多崩溃瞬间的信息。
按时间范围过滤非常实用。比如你知道故障发生在凌晨2点到2点30分之间:
journalctl --since "2025-06-15 02:00:00" --until "2025-06-15 02:30:00"
按服务单元过滤,只查看某个具体服务的日志:
journalctl -u nginx.service
如果服务崩溃后自动重启过,查看该服务所有实例的日志,加上--merged参数:
journalctl -u nginx.service --merged
优先级过滤能快速定位严重问题。日志级别从0(emerg)到7(debug),排查故障时优先看0到3级:
journalctl -p 3 -b
这条命令只输出error、critical、alert、emergency级别的日志,直接过滤掉大量info和debug噪音。实际工作中,我习惯先跑这条命令快速扫描,发现可疑时间点后再扩大范围深挖。
内核日志与硬件故障排查硬件层面的问题,比如内存损坏、磁盘I/O错误、驱动异常,都会记录在内核日志中。用journalctl查看内核消息:
journalctl -k -b
如果怀疑内存问题,搜索Memory或OOM关键字:
journalctl -k -b | grep -i "memory\|oom"
OOM Killer是Linux在内存耗尽时的自我保护机制,它会杀掉占用内存最多的进程。日志中如果出现"Out of memory"或"Killed process",说明服务器内存不足,某个进程被系统强制终止了。这时候不是去骂OOM Killer,而是要查为什么内存被吃光。
磁盘I/O错误通常表现为"Buffer I/O error"或"EXT4-fs error"。这类错误一旦出现,必须立即检查硬盘健康状态:
smartctl -a /dev/sda
重点看Reallocated_Sector_Ct和Pending_Sector这两个值。如果重分配扇区数持续增长,硬盘已经进入不可逆的损坏过程,唯一的正确操作是立刻备份数据并更换磁盘,不要抱任何侥幸心理。
应用服务日志的深度分析Nginx和Apache的访问日志和错误日志,是排查Web服务故障的第一手资料。默认路径在/var/log/nginx/和/var/log/apache2/下。错误日志中,重点关注返回码5xx的请求,以及"upstream timed out"这类连接上游服务的超时错误。
快速统计某个时间段内状态码分布:
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn
如果500错误集中爆发,先看错误日志中对应时间段的记录:
grep "2025/06/15 02:" /var/log/nginx/error.log
PHP-FPM的慢日志是排查PHP应用性能瓶颈的利器。在php-fpm.conf中开启慢日志:
slowlog = /var/log/php-fpm/slow.log request_slowlog_timeout = 5s
任何执行超过5秒的PHP脚本都会被记录,包括完整的堆栈跟踪信息。这能直接定位到是哪个文件、哪个函数、甚至哪一行代码导致的慢查询或死循环。
MySQL的慢查询日志同样重要。在my.cnf中配置:
slow_query_log = 1 slow_query_log_file = /var/log/mysql/slow.log long_query_time = 2
用mysqldumpslow工具分析慢日志:
mysqldumpslow -s t -t 10 /var/log/mysql/slow.log
这条命令按总时间排序,输出最耗时的前10条SQL。很多时候服务器负载飙升,根源就是一条没加索引的SQL在高峰期被大量执行。
SSH登录安全审计与入侵排查auth.log记录了所有认证相关的事件,包括SSH登录、sudo提权、用户创建等。路径在/var/log/auth.log。排查服务器是否被入侵,这是第一个要检查的日志。
查看所有成功的SSH登录记录:
grep "Accepted" /var/log/auth.log
查看失败的登录尝试,判断是否有人在暴力破解:
grep "Failed password" /var/log/auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn
如果某个IP有上百次失败尝试,紧接着出现一次成功登录,那基本可以确定服务器已经被攻破。此时要立刻检查这个IP登录后的操作记录,查看/var/log/auth.log中该IP之后的所有活动,同时检查~/.bash_history是否被清空或篡改。
查看最近有哪些用户获得了root权限:
grep "sudo" /var/log/auth.log | grep "COMMAND"
如果发现不明用户执行了sudo命令,或者熟悉的用户在异常时间执行了敏感操作,需要立即核实。
系统资源监控与日志关联分析单纯看日志文本有时不够直观,需要结合系统资源使用情况做关联分析。sar命令是sysstat包中的工具,能回溯查看CPU、内存、磁盘I/O的历史数据。Ubuntu默认不会安装,需要手动安装:
apt install sysstat
安装后会自动开始采集数据。查看昨天的CPU使用情况:
sar -u -f /var/log/sysstat/sa$(date +%d -d yesterday)
查看内存使用历史:
sar -r -f /var/log/sysstat/sa$(date +%d -d yesterday)
当从应用日志中发现某个时间段响应变慢时,立刻用sar回溯那个时间点的系统负载。如果CPU idle接近0,而iowait很高,说明磁盘I/O是瓶颈,这时候去查是什么进程在疯狂读写磁盘:
iotop -b -n 1
如果CPU user态很高,说明应用代码在大量消耗CPU,结合top或htop找到对应进程,再根据进程日志深入分析。
自定义日志收集与集中管理单台服务器的日志分析还能应付,但如果是多台服务器集群,逐台登录查看日志效率太低。rsyslog是Ubuntu自带的日志转发工具,可以配置将所有服务器的日志集中发送到一台日志服务器。
在日志服务器上开启rsyslog的TCP接收,编辑/etc/rsyslog.conf:
module(load="imtcp") input(type="imtcp" port="514")
在客户端服务器上配置转发规则,同样编辑rsyslog.conf,添加:
*.* @@日志服务器IP:514
重启rsyslog服务后,所有日志都会实时发送到中心服务器。这样即使某台服务器彻底宕机无法登录,它的日志也已经安全保存在远程服务器上了。
对于更复杂的场景,可以引入Loki或ELK这类日志聚合系统。Loki相比ELK更轻量,和Grafana集成后能实现日志的实时搜索、过滤和可视化告警。配置Promtail采集日志并发送给Loki,然后在Grafana中创建仪表盘,设置当错误日志频率超过阈值时自动发送告警通知。
日志轮转与存储策略日志不管理会撑爆磁盘,这本身就会引发新的故障。Ubuntu使用logrotate来管理日志轮转,配置文件在/etc/logrotate.conf和/etc/logrotate.d/目录下。检查某个日志的轮转策略,比如nginx:
cat /etc/logrotate.d/nginx
关键参数包括:daily/weekly/monthly决定轮转频率,rotate决定保留多少份历史日志,compress决定是否压缩,maxsize限制单个日志文件大小。根据服务器磁盘空间和日志产生速度合理调整这些参数。对于高流量服务器,建议按大小轮转而不是按时间,设置maxsize 500M,避免一天之内日志就膨胀到几十GB。
journalctl的日志也有存储限制,在/etc/systemd/journald.conf中配置:
SystemMaxUse=2G
限制journal日志最多占用2GB磁盘空间,防止/var/log/journal目录无限增长。
实战排查思路总结面对一个未知故障,我的固定排查路径是:先用journalctl -p 3 -b快速扫描严重错误,确认问题发生的大致时间点。然后根据故障现象缩小范围,Web服务问题看Nginx错误日志和PHP慢日志,数据库问题看MySQL慢查询和错误日志,系统负载问题用sar回溯资源使用情况,安全问题查auth.log。多个日志交叉比对时间戳,通常能在10分钟内锁定根因。日志不会说谎,但它也不会主动告诉你答案,你需要带着明确的问题去问它,用正确的命令去筛选和关联信息。每一次故障都是完善监控和日志覆盖的机会,修完问题后记得把这次的关键指标加入监控告警规则,避免同样的问题再次发生时才被动发现。
