事情本身不复杂,线索都在日志里。应用日志按行同步刷盘,iostat 里 w/s 只有三千但 w_await 到 12ms,接口偶发超时,机器用的是普通云盘不是 ESSD,系统 CentOS 7.9。
第一反应是「文件系统日志模式是 data=journal,写两次」,验证下来不成立。
真正麻烦的地方在于,几个原因的现象几乎一样。每条日志都调用 fsync,每次都要等落盘。也可能是日志文件和数据库数据在同一块盘上。
不容易想到的是,目录项更新也同步,多出一次元数据写。
动手时先看进程的 fsync 调用频率
strace -f -c -p $(pgrep -f order-service)
接着把日志改成缓冲写并定时刷盘
grep -n 'sync\|fsync' /opt/app/conf/logback.xml | head
然后把日志目录迁到独立云盘
df -h /var/log && lsblk -o NAME,SIZE,MOUNTPOINT
复核写入延迟与抖动幅度
iostat -xmd 1 10 /dev/vdb
恢复的判定其实很直接。fsync 次数降到每秒几十次,w_await 稳定在 2ms 以内,接口的超时告警随之消失。
这里还有个坑。日志落盘要按重要性分级,审计日志同步写、业务日志缓冲写;fsync 的代价在普通云盘上尤其明显。这类问题最好一次改到位,反复小改反而容易把原因搅混。
