现场是这样的。CentOS 7.9 客户端 mount -t nfs4 挂存储,命令卡住三分钟才返回 timed out,dmesg 里刷 nfs: server 10.0.3.21 not responding, timed out,挂上之后读小文件正常,一碰大目录 ls 又卡住。
中间走过弯路,把「安全组只放了 2049,rpcbind 的 111 端口被挡,协商阶段先超时」当成主因,改完现象没变。
排查方向其实有限,先把可能性排一排。用的是 hard 挂载又没设 timeo 和 retrans,服务端不回包就一直重试下去;服务端的 nfsd 线程数只有 8,并发一多请求排队,客户端等不到回复;MTU 不一致,大包被中间设备丢掉,小请求正常大请求卡住。
动手时先确认导出路径和协议版本
showmount -e 10.0.3.21 && rpcinfo -p 10.0.3.21
然后用 soft 加超时参数临时挂载验证
mount -t nfs4 -o soft,timeo=100,retrans=3 10.0.3.21:/data /mnt/data
接着抓包看请求卡在哪一步
tcpdump -i eth0 -nn host 10.0.3.21 and port 2049 -c 50
等前面都确认过,再确认服务端线程数和连接数
cat /proc/fs/nfsd/threads; ss -tn state established '( sport = :2049 )' | wc -l
别只看报错消失,验证要多做一步。mount 在十秒内返回,ls 大目录不再卡顿,dmesg 里半小时内没有新的 not responding,读写测试的延迟稳定在两毫秒以内。
容易忽略的是,soft 挂载在服务端长时间不可用时直接返回 EIO,数据库这类应用宁可 hard 也不能丢写,取舍要看业务;timeo 的单位是 0.1 秒,写 100 就是十秒,很多人在这里少写一个零。这类问题最好一次改到位,反复小改反而容易把原因搅混。
