16、主机故障排查指南
主机故障排查指南
1. 高 I/O 等待问题
当 I/O 请求阻塞进程执行其他工作时,会出现显著的 I/O 等待(iowait)。通常,高 iowait 会导致主机负载增加,CPU 使用率可能高于正常水平。因为当 CPU 等待磁盘响应时,它为系统其他部分服务的时间就会减少。
高 iowait 可能由以下原因导致:
- 磁盘老化、速度慢或出现故障。
- 应用程序进行大量的磁盘读写操作。
- 在虚拟化环境中,网络附属存储速度慢。
所有系统都会有一定的 iowait,而且现代 CPU 的速度比存储设备快。不过,单独的高 iowait 并不一定意味着存在问题,有些高 iowait 的系统仍能正常运行,而有些则会出现明显的瓶颈。一般将持续超过 30% 的 iowait 视为高 iowait。
可以使用
iostat
和
iotop
这两个命令行工具来排查高 iowait 问题。
1.1 iostat 工具
iostat
用于报告设备的 CPU 和 I/O 统计信息,可帮助判断系统是否存在 iowait。若未默认安装,可使用包管理器安装
sysstat
包。
为了更好地观察问题,需要在一段时间内对系统进行轮询。示例命令如下:
$ iostat -xz 1 20
示例输出:
avg-cpu: %user %nice %system %iowait %steal %idle
6.25 0.00 27.08 66.67 0.00 0.00
Device r/s rkB/s w/s wkB/s %util ...
vda 0.00 0.00 1179.00 712388.00 100.00 ...
-xz
标志:以扩展统计格式显示仅活动的设备。
w/s
列:显示
vda
设备每秒执行大量写请求(1179.00)。
%iowait
:CPU 约 66.67% 的时间在等待未完成的磁盘请求。
%util
:磁盘利用率为 100%,表明磁盘非常繁忙。
由此可判断主机存在持续的高 iowait 问题,且问题出在
vda
设备上。接下来可使用
iotop
工具查找可能导致 iowait 增加的进程。
1.2 iotop 工具
iotop
以类似
top
的格式显示 I/O 使用情况,能提供主机 I/O 的概述,并深入到进程级别查找可能导致大量磁盘 I/O 的进程。多数发行版未默认包含该工具,需使用包管理器进行安装。
运行
iotop
时,可使用以下命令限制输出,仅显示执行 I/O 的活动进程,并使用批量模式持续轮询,使输出简洁,揭示可能的 I/O 模式。此命令需要提升权限,可使用
sudo
或特权用户运行:
$ sudo iotop -oPab
示例输出:
Total DISK READ: 15.04 M/s | Total DISK WRITE: 446.28 M/s
Current DISK READ: 15.04 M/s | Current DISK WRITE: 321.58 M/s
PID PRIO USER DISK READ DISK WRITE SWAPIN IO COMMAND
88576 be/4 bob 512.00 M 616.81 M 0.00 % 83.26% heavy-io
469 rt/4 root 0.00 B 0.00 B 0.00 % 0.00% multipathd -d -s
--snip--
-oPab
标志:使
iotop
在批量模式下仅显示执行 I/O 的进程,并显示累积统计信息。
IO
列:
heavy-io
命令的 I/O 使用率为 83.26%,其进程 ID(PID)为 88576。由于报告中其他进程的 I/O 使用量不大,可推测
heavy-io
进程是高 iowait 的部分原因。
1.3 后续步骤
在检查统计信息并找到导致高 iowait 的进程 ID 后,可以:
- 了解该应用程序的用途。若有源代码或配置文件,检查进程可访问的磁盘操作或文件。
- 若使用云服务提供商的虚拟机,检查磁盘是否有足够的 I/O 操作配额,可通过检查磁盘指标进行确认,并调整配额以平衡负载。
- 若上述方法都无效,可使用
lsof
检查打开的文件,
strace
跟踪进程的系统调用,
dmesg
查看硬件内核错误。
2. 主机名解析失败问题
当服务需要连接另一个服务时,通常会使用域名系统(DNS)查找目标服务的 IP 地址。DNS 就像一个主机 IP 地址映射目录,让我们可以使用像
google.com
这样的域名,而无需记住具体的 IP 地址。
假设一个应用程序尝试连接本地环境中的 Postgres 数据库,日志中出现如下错误:
psql: error: could not translate host name "db.smith.lab" to address: Temporary failure in name resolution
这表明应用程序无法解析
db.smith.lab
的 DNS 记录。下面介绍一些排查此错误的工具。
2.1 resolv.conf 文件
在 Linux 主机上排查 DNS 问题,首先要查看
/etc/resolv.conf
文件,它提供了要查询的 DNS 服务器信息以及一些特殊选项(如超时或安全设置)。以下是一个典型 Ubuntu 主机的
resolv.conf
文件示例:
# This file is managed by man:systemd-resolved(8). Do not edit.
#
# This is a dynamic resolv.conf file for connecting local clients to the
# internal DNS stub resolver of systemd-resolved. This file lists all
# configured search domains.
#
# Run "resolvectl status" to see details about the uplink DNS servers
# currently in use.
#
# Third party programs must not access this file directly, but only through
# the symlink at /etc/resolv.conf. To manage man:resolv.conf(5) in a
# different way, replace this symlink by a static file or a different
# symlink.
#
# See man:systemd-resolved.service(8) for details about the supported
# modes of operation for /etc/resolv.conf.
nameserver 127.0.0.53
options edns0 trust-ad
该文件由
systemd-resolved
服务管理,不要手动编辑,否则下次主机或服务重启时会被覆盖。
nameserver
关键字指定要查询的 DNS 服务器 IP 地址,此例中为
127.0.0.53
,即本地解析器。若本地解析器不知道查询答案,会将请求转发到上游 DNS 服务器。
options
关键字用于修改解析器的特定属性。
edns0
选项启用 DNS 协议的扩展功能;
trust-ad
选项在所有出站 DNS 查询中包含认证数据,并在响应中保留认证数据,增强 DNS 安全性。
2.2 resolvectl 工具
由于使用了
systemd-resolver
,可以使用
resolvectl
工具与本地解析器交互。若未安装,可通过包管理器安装。
要查看本地 DNS 解析器(
127.0.0.53
)将未知请求转发到哪些上游 DNS 服务器,可使用以下命令:
$ resolvectl dns
示例输出:
Global:
--snip--
Link 2 (enp0s3): 10.0.2.3
结果显示,对于接口
enp0s3
,下游 DNS 服务器设置为
10.0.2.3
。主机上的应用程序尝试连接
db.smith.lab
时,会先向
127.0.0.53
发送 DNS 请求,若本地解析器不知道答案,会将请求转发到
10.0.2.3
。若
10.0.2.3
知道答案,会返回给本地解析器,再由本地解析器返回给用户;若不知道,会继续向上游转发,直到找到该域名的权威服务器。
2.3 dig 工具
dig
用于查询 DNS 服务器并显示结果,在排查 DNS 问题或获取主机 IP 地址时非常有用。只需将主机名传递给
dig
,它就会返回查询和响应服务器的相关信息。
查询本地解析器中
db.smith.lab
的 IP 地址:
$ dig db.smith.lab
示例输出:
; DiG 9.16.1-Ubuntu db.smith.lab
;; global options: +cmd
;; Got answer:
;; -HEADER- opcode: QUERY, status: SERVFAIL, id: 35816
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 65494
;; QUESTION SECTION:
;db.smith.lab. IN A
;; Query time: 32 msec
;; SERVER: 127.0.0.53#53(127.0.0.53)
--snip--
- `status` 字段显示查询状态,`SERVFAIL` 表示无法给出答案,因为本地 DNS 不知道 `db.smith.lab` 的位置。
- `QUESTION SECTION` 显示发送给 DNS 服务器的查询,这里是查询 `db.smith.lab` 的 A 记录(将域名映射到 IP 地址的 DNS 记录类型)。
- `SERVER` 部分显示查询所使用的 DNS 服务器,即本地解析器 `127.0.0.53`。
查询上游服务器中
db.smith.lab
的 IP 地址:
$ dig @10.0.2.3 db.smith.lab
结果同样显示
SERVFAIL
,说明上游服务器也无法提供该主机名的答案。
为确保本地和上游 DNS 服务器正常工作,查询
google.com
的 A 记录:
$ dig google.com
示例输出:
;; -HEADER- opcode: QUERY, status: NOERROR, id: 15154
;; QUESTION SECTION:
;google.com. IN A
;; ANSWER SECTION:
google.com. 300 IN A 142.250.72.78
;; Query time: 36 msec
;; SERVER: 127.0.0.53#53(127.0.0.53)
状态为
NOERROR
,且在
ANSWER SECTION
中获得了
google.com
的 A 记录
142.250.72.78
,说明 DNS 服务器可以正常解析其他主机名,但不知道
db.smith.lab
的 A 记录。
2.4 后续步骤
若 DNS 能正常解析其他主机名,但特定主机名解析失败,问题可能出在 DNS 解析器缺少该主机名到 IP 地址的映射信息。
- 若使用 Amazon Route53 等服务托管 DNS,确保记录未被配置管理软件或人为错误删除。
- 若本地管理 DNS 服务器,检查 A 记录是否存在。若不存在,可能是配置文件存在语法错误,或者需要重启 DNS 服务器以读取新记录。
3. 磁盘空间不足问题
磁盘空间最终会耗尽,此时需要找出占用大量空间的原因,可能是应用程序异常、日志文件无限制增长或 Docker 镜像堆积等。
3.1 df 工具
df
用于显示主机上所有挂载文件系统的可用磁盘空间。通常使用
-h
标志以人类可读的格式显示结果。
$ df -h
示例输出:
Filesystem Size Used Avail Use% Mounted on
/dev/vda1 25G 25G 0 100% /
--snip--
此例中,
/dev/vda1
设备已使用了 25G 的全部磁盘空间,文件系统挂载在根目录
/
。若主机有多个挂载磁盘,输出中也会显示。
3.2 find 工具
find
可在文件系统中搜索目录和文件,并可根据特定条件或目录进行过滤,还能按文件大小查找。
由于运行
df
命令后知道根文件系统空间不足,可使用
find
命令在根文件系统中搜索大于 100M 的文件,并按大小排序,显示前 10 个结果。
$ sudo find / -type f -size +100M -exec du -ah {} + | sort -hr | head
示例输出:
10G /var/log/php7.2-fpm.log
5G /var/lib/docker/containers/.../...a3b76-json.log
--snip--
此输出显示
/var/log/php7.2-fpm.log
文件大小为 10G,
/var/lib/docker/containers
中的一个 Docker 容器日志文件大小为 5G,这两个文件共占用了 15GB 磁盘空间。通常,这类应用程序日志应该定期轮转,不应该变得如此之大。
3.3 lsof 工具
lsof
用于列出主机上打开的文件,可根据进程或用户进行搜索。使用
lsof
查找正在写入
/var/log/php7.2-fpm.log
文件的进程:
$ sudo lsof /var/log/php7.2-fpm.log
示例输出:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
php-fpm7. 23496 root 2w REG 252,1 1048580000 1529 /var/log/php7.2-fpm.log
--snip--
结果显示,
php-fpm7
进程(PID 为 23496)正在写入该日志文件。文件描述符
2w
表示文件描述符为 2,且以写入模式打开。
3.4 后续步骤
当磁盘空间不足且找到占用大量空间的文件后,由于日志文件正在被使用,直接截断或删除可能导致进程崩溃或停止写入日志。可以:
- 查看日志输出,检查是否有错误信息,或者应用程序日志级别是否设置为调试模式。
- 检查 Docker 容器日志内容,看是否与该日志文件存在关联,可能该进程在容器内运行。
- 确保主机配置了
logrotate
命令,按计划压缩和轮转日志文件,避免日志文件无限制增长。Ubuntu 系统中,
logrotate
配置文件位于
/etc/logrotate.d/
目录。
综上所述,通过以上工具和方法,可以有效地排查主机的高 I/O 等待、主机名解析失败和磁盘空间不足等常见问题。在实际操作中,要根据具体情况灵活运用这些工具,逐步定位和解决问题。
主机故障排查指南(续)
4. 总结与流程梳理
为了更清晰地展示上述故障排查的流程,下面通过 mermaid 流程图进行梳理。
graph LR
classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px
classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px
A([开始排查]):::startend --> B{故障类型?}:::decision
B -->|高 I/O 等待| C(使用 iostat 检查):::process
C --> D{是否高 iowait?}:::decision
D -->|是| E(确定受影响设备):::process
E --> F(使用 iotop 查找进程):::process
F --> G(分析进程及后续处理):::process
B -->|主机名解析失败| H(查看 resolv.conf 文件):::process
H --> I(使用 resolvectl 查看上游 DNS):::process
I --> J(使用 dig 查询 DNS):::process
J --> K{解析是否失败?}:::decision
K -->|是| L(检查 DNS 记录及配置):::process
B -->|磁盘空间不足| M(使用 df 查看空间):::process
M --> N{是否空间不足?}:::decision
N -->|是| O(使用 find 查找大文件):::process
O --> P(使用 lsof 确定进程):::process
P --> Q(处理文件及配置 logrotate):::process
5. 工具使用对比
为了更直观地对比上述使用的工具,下面通过表格进行展示:
故障类型
工具名称
工具作用
使用示例
高 I/O 等待
iostat
报告设备的 CPU 和 I/O 统计信息
iostat -xz 1 20
高 I/O 等待
iotop
以类似 top 的格式显示 I/O 使用情况,定位进程
sudo iotop -oPab
主机名解析失败
resolv.conf
提供要查询的 DNS 服务器信息及特殊选项
查看
/etc/resolv.conf
文件
主机名解析失败
resolvectl
与本地解析器交互,查看上游 DNS 服务器
resolvectl dns
主机名解析失败
dig
查询 DNS 服务器并显示结果
dig db.smith.lab
、
dig @10.0.2.3 db.smith.lab
、
dig google.com
磁盘空间不足
df
显示主机上所有挂载文件系统的可用磁盘空间
df -h
磁盘空间不足
find
在文件系统中搜索符合条件的大文件
sudo find / -type f -size +100M -exec du -ah {} + | sort -hr | head
磁盘空间不足
lsof
列出主机上打开的文件,确定写入进程
sudo lsof /var/log/php7.2-fpm.log
6. 常见问题及注意事项
在使用这些工具进行主机故障排查时,可能会遇到一些常见问题,下面进行总结:
6.1 高 I/O 等待问题
工具安装问题
:
iostat
依赖
sysstat
包,
iotop
多数发行版未默认安装。在使用前,需通过包管理器进行安装,如
apt-get install sysstat
或
yum install sysstat
安装
sysstat
,
apt-get install iotop
或
yum install iotop
安装
iotop
。
数据准确性
:
iostat
首次输出的数据是自上次主机启动以来的统计信息,在当前排查场景中可能不相关,分析时需注意。
6.2 主机名解析失败问题
resolv.conf 文件修改
:该文件由
systemd-resolved
服务管理,手动修改可能会在主机或服务重启时被覆盖。若需自定义配置,可参考文件中的注释说明进行操作。
DNS 服务器配置
:本地解析器和上游 DNS 服务器的配置可能因网络环境不同而有所差异,需根据实际情况进行检查和调整。
6.3 磁盘空间不足问题
find 命令性能
:在大文件系统中使用
find
命令搜索大文件可能会消耗大量时间和系统资源。可根据实际情况调整搜索条件,如缩小搜索范围或调整文件大小阈值。
lsof 权限问题
:
lsof
命令需要提升权限才能运行,可使用
sudo
或特权用户执行。
7. 实际案例分析
下面通过一个实际案例,综合运用上述工具和方法进行故障排查。
假设某服务器出现响应缓慢的情况,初步怀疑是高 I/O 等待或磁盘空间不足问题。
第一步:检查磁盘空间
$ df -h
输出显示
/dev/vda1
设备已使用 100% 的 50G 磁盘空间,确定磁盘空间不足。
第二步:查找大文件
$ sudo find / -type f -size +100M -exec du -ah {} + | sort -hr | head
发现
/var/log/app.log
文件占用了 30G 空间。
第三步:确定写入进程
$ sudo lsof /var/log/app.log
得知
app-process
进程(PID 为 12345)正在写入该日志文件。
第四步:查看日志内容
$ tail -n 100 /var/log/app.log
发现日志中存在大量重复的错误信息,推测是应用程序异常导致日志文件不断增长。
第五步:处理问题
调整应用程序配置,修复导致错误的问题。
配置
logrotate
对
app.log
文件进行定期轮转和压缩。
经过上述处理,服务器响应恢复正常,磁盘空间问题得到解决。
8. 结论
主机故障排查是系统管理中的重要工作,通过合理运用
iostat
、
iotop
、
resolv.conf
、
resolvectl
、
dig
、
df
、
find
和
lsof
等工具,结合科学的排查流程和方法,可以有效地定位和解决高 I/O 等待、主机名解析失败和磁盘空间不足等常见问题。在实际操作中,要注意工具的安装和使用细节,根据具体情况灵活调整排查策略,确保系统的稳定运行。同时,定期对系统进行监控和维护,及时发现和处理潜在问题,也是保障系统性能的关键。