如何定位高iowait进程并每日记录top、iotop、iostat输出
高iowait进程定位方法
- 实时定位直接使用
iotop:运行命令iotop -oP,-o参数会过滤出当前正在进行IO操作的进程,-P参数仅展示进程而非线程,第一列PID即为高IO消耗进程ID,通过DISK READ、DISK WRITE列可直接查看进程的读写速率。 - 如需统计周期内的IO占用,使用
pidstat:运行命令pidstat -d 1 10,每1秒采样1次共采样10次,kB_rd/s、kB_wr/s分别对应进程每秒读写的KB数,%wait为进程IO等待的时间占比,可精准定位高IO消耗进程。 - 拿到PID后关联进程身份:运行命令
ps -ef | grep <PID>,即可确认进程是否为JBoss EAP 7主进程或其派生的子进程。
监控数据持续采集方案
你可以通过如下脚本持续采集所需的监控数据,直到问题解决后停止即可:
- 新建采集脚本
io_monitor.sh,内容如下:
#!/bin/bash # 日志存储目录可自行修改 LOG_DIR=/var/log/io_monitor mkdir -p $LOG_DIR while true do DATE=$(date +%Y%m%d) TIMESTAMP=$(date +%Y%m%d_%H%M%S) # 采集top数据 echo "===== $TIMESTAMP TOP 输出 =====" >> $LOG_DIR/top_$DATE.log top -b -n 1 >> $LOG_DIR/top_$DATE.log # 采集iotop数据 echo "===== $TIMESTAMP IOTOP 输出 =====" >> $LOG_DIR/iotop_$DATE.log iotop -b -n 1 -P >> $LOG_DIR/iotop_$DATE.log # 采集iostat扩展数据 echo "===== $TIMESTAMP IOSTAT 输出 =====" >> $LOG_DIR/iostat_$DATE.log iostat -x 1 3 >> $LOG_DIR/iostat_$DATE.log # 采样间隔可自行调整,此处为10分钟采样一次,故障高发期可改为60秒 sleep 600 done
- 给脚本赋予执行权限:
chmod +x io_monitor.sh - 后台启动脚本即可持续采集:
nohup ./io_monitor.sh & - 可选配置日志自动清理:运行
crontab -e添加如下定时任务,每日自动清理7天前的旧日志避免占满磁盘:
0 1 * * * find /var/log/io_monitor -type f -mtime +7 -delete
根因排查建议
- 若确认高IO进程为JBoss EAP 7进程,优先排查三类常见问题:
- 应用是否存在未优化的高频数据库操作,比如无索引的全表扫描、批量未提交的写入事务,导致数据库数据文件、日志文件IO被打满
- 应用日志配置是否合理,比如是否开启了DEBUG级别的全量日志、日志异步刷盘配置是否失效,导致大量日志写入占满磁盘IO
- JVM堆内存配置是否过小,导致频繁触发Full GC同时伴随大量swap分区交换,可通过
free -m查看swap占用情况,结合jstat -gcutil <JBOSS_PID> 1000查看GC频率确认是否存在该问题
- 若高IO进程不属于JBoss,排查服务器上的其他定时任务(比如全量备份、日志切割)、第三方采集程序、其他业务进程的IO占用,确认是否存在资源抢占
- 排查磁盘本身健康状态:通过
smartctl -a /dev/<磁盘名>查看是否存在坏道,通过df -h查看磁盘是否已满、df -i查看inode是否耗尽,这两类情况都会导致写入异常引发高iowait
内容的提问来源于stack exchange,提问作者GouthamRio
相关产品推荐
相关产品推荐

