Linux 上接口卡顿异常排查(IO 异常)
前提:
客户现场有一台服务器,由于现场断电,导致服务器强制重启了,重启之后web可以访问但接口异常卡顿。
排查故障:
-
第一个就怀疑是网络问题,因为服务只是重启了,web也能登录,所以怀疑是企业的路由器故障了,导致web卡顿,但是经过排查、测速,并不是这个原因
-
第二个怀疑是系统资源不足,但是排查了内存和磁盘占用之后发现并没有异常
# 查看内存占用 top # 查看磁盘占用 df -h -
第三个排查业务代码,使用阿里巴巴的Arthas工具
# 由于我的服务是用docker部署,需要进入容器内进行监控 docker exec -it my-web bash # 下载arthas包 curl -O https://arthas.aliyun.com/arthas-boot.jar # 启动监控,注意如果服务器无法联网,需要下载arthas-bin.zip包解压之后执行 ./install-local.sh 安装所需组件,再启动监控 java -jar arthas-boot.jar # 启动之后根据提示选择对应的java进程 比如 1 # 使用trace指令监控卡顿的接口函数,这个指令可以记录函数的调用耗时 trace com.chemcyber.web.myflow.screen.service.impl.FlowManageScreenServiceImpl getOperationTicket
经过排查,找到了查询慢的sql,拿到数据库里面直接执行,发现竟然时快时慢。。。真是头大
-
第四步,经过不断的网上查找,以及提问AI,建议我排查一下系统IO,于是
# 监控IO占用 iostat -x 1
可以看到IO占用竟高达99%,到这里总算是找到了大致的方向了,于是继续排查
iotop -oP可以看到是mysql占用了大量的IO(这个截图找不到了),经过一顿搜索,卡顿的原因是服务器异常断电重启后,MySQL自动进行崩溃修复,因此占用大量IO,以下是临时缓解办法(记得修改之前先查询当前配置,方便后续恢复回去)。
-- MySQL临时降低写入压力 SET GLOBAL innodb_flush_log_at_trx_commit = 2; SET GLOBAL sync_binlog = 0; -- 优化InnoDB配置 SET GLOBAL innodb_io_capacity = 2000; SET GLOBAL innodb_io_capacity_max = 4000; -- MySQL关键调整(立即生效) SET GLOBAL innodb_io_capacity=4000; SET GLOBAL innodb_flush_neighbors=0; -- SSD必须关闭 SET GLOBAL innodb_adaptive_flushing=ON; -- 增加缓冲池 SET GLOBAL innodb_buffer_pool_size = 12G; # 建议物理内存的50-70% -
再次查看IO状态,发现一顿操作下来,IO占用竟然没有丝毫改善。。。
# 查询磁盘写入速度(该命令会创建一个名为testfile的1GB文件,并将零值数据写入该文件。通过使用oflag=direct参数,可以绕过操作系统缓存,直接测试磁盘的写入性能) dd if=/dev/zero of=testfile bs=1G count=1 oflag=direct # 等待命令执行完成。在完成后,dd命令将显示读取的数据量、所用的时间和读取速度等信息。
磁盘写入速度只有100MB/S,这里判断可能是磁盘故障了,没办法了,只能等mysql自动修复了,第二天再看看。
-
一觉睡醒后,第二天果然恢复正常了(记得把之前改的mysql配置恢复回去)。
-
后续处理:排查服务器硬盘是否异常,需要更换硬盘,如果服务器做了Raid阵列(比如Raid5),可能是有其中一块盘坏了,导致整体写入速度变慢。
-
Mysql
8 引用
-
Linux
58 引用
-
故障排查
1 引用
-
Springboot
26 引用
牛逼 南瓜佬 不明觉厉
我是菜菜
大佬,不像我,只会 rm -rf *
大佬
666
666 学到了