dmesg -T | grep -A5 'blocked for more than' sudo cat /proc/<pid>/stack echo w | sudo tee /proc/sysrq-trigger sysctl kernel.hung_task_timeout_secs
dmesg 里出现 INFO: task java blocked for more than 120 seconds,业务线程全部卡住但进程还在,top 显示 CPU 空闲,第一眼很难想到是内核在报,重启一次又能撑几小时。先别急着动参数,把报错原文和时间点记下来,顺序反了容易白折腾。
原因不复杂,任务在不可中断睡眠里待的时间超过 hung_task_timeout_secs,多半是磁盘或者网络存储卡住,也可能是驱动死锁,内核只给一行汇总需要自己抓栈。
「hung_task 阻塞」改完先别急着全量,挑一台机器放半天,真有问题这段时间就能看出来。动手前把原文件复制一份带时间戳,出问题立刻换回去,比现场分析快得多。
一次只改一处,改完立刻验证,几个改动叠在一起,出问题就说不清是谁导致的。
处理上按这个顺序:先在 dmesg 里找到 blocked 行对应的 pid 和进程名 确认是不是业务进程;读 proc 下的 stack 或者用 sysrq 的 w 输出全部栈 一次能看清所有阻塞点;确认卡住的设备之后 再决定摘盘还是重启机器 顺序反了会丢数据。
改完只确认一件事:dmesg 不再出现 blocked 提示 目标进程从 D 状态恢复 业务线程也重新跑起来。
