Jenkins 构建卡死不结束速查:executor 排队、input 等待与测试挂死
更新时间:2026-10-24。FAQ 速查页,面向构建进度条一动不动、转了几小时圈既不成功也不失败的同学。Jenkins 构建卡死的本质不是「慢」而是「在等一个永远不会来的事件」:等一个空闲执行器、等人在 input 步骤点确认、等一个挂死的测试进程退出、等 shell 读到永远不会来的标准输入。病因收敛在六根轴上:执行器全被占满或标签对不上导致排队、流水线停在 input 步骤没人点、测试框架或子进程死锁挂死、shell 命令在阻塞读 stdin、节点 CPU/内存打满导致一切龟速、以及压根没配超时兜底让一个挂死拖死整条流水线。顺一遍基本必中。如果是节点直接灰 offline,先转 Jenkins 节点离线速查。
本文要回答的问题
- 构建一直
Waiting for next available executor,是没执行器还是配置错了? - 构建日志停在某一行不动,怎么判断它在等什么?
- input 步骤挂着的构建,去哪里找确认按钮?
- 测试进程挂死了,怎么在节点上确认并杀掉?
- 怎么给流水线配超时,让卡死的构建自己死掉?
一、报错原文与典型现象
卡死的「报错」其实是「没有报错」——日志停住、进度条不动。线索分散在三处:队列页的提示、构建日志的最后一行、以及节点机器上的进程现场(控制器地址以 jenkins.example.com 占位,路径以 /proj/demo 占位):
# 构建排队阶段
Waiting for next available executor on 'linux-docker'
# 或标签根本不存在
There are no nodes with the label 'win-msvc'# 构建日志停在 input 步骤(进度条卡在中间)
[Pipeline] input
Input requested# 构建日志停在某条测试命令(再无新行)
[Pipeline] sh
+ ./run-tests.sh --suite full
(此后数小时无任何输出)读现象先分三段:排队页都进不去 = 没排到执行器;日志停在 Input requested = 在等人;日志停在某条命令之后再无输出 = 命令本身挂了。三段对应完全不同的处置路径,先定性再动手。
二、病因处置速查表
| 报错现象 / 场景 | 可能原因 | 快速验证 | 处置 |
|---|---|---|---|
| Waiting for next available executor | 执行器全被占满或数量配太少 | 节点列表看各节点执行器占用 | 等占坑构建结束;扩容执行器或节点 |
| There are no nodes with the label | 流水线 label 没有匹配节点 | 节点列表搜该标签 | 修标签或给节点补标签 |
| 日志停在 Input requested | input 步骤没人点确认 | 构建页或 Blue Ocean 找确认按钮 | 点 Proceed/Abort;给 input 配 timeout |
| 日志停在某条命令后无输出 | 测试/子进程死锁挂死 | 节点上 ps aux 找该进程看状态 | 杀进程;修被测程序的死锁 |
| shell 命令卡住且脚本里有交互命令 | 命令在阻塞读 stdin | 日志停在这条命令;进程 wchan 为 read | 命令加 < /dev/null 或去交互参数 |
| 整台节点上所有构建都龟速 | 节点 CPU/内存/IO 打满 | 节点上 top / dstat 看负载 | 降并发、迁移任务、扩容节点 |
| 构建跑了远超正常时长还在跑 | 没配超时兜底 | 看 Jenkinsfile 有无 timeout 块 | 配 options timeout 或 Build Timeout 插件 |
三、排查决策图
下面这张图是标准排查路线,颜色按角色区分:红是报错入口与命中的根因,蓝是排查动作,绿是通过分支,橙是修复动作,紫是防复发沉淀。
读这张图抓分水岭:先看构建「到底开没开始」——队列页在等执行器走左支,归调度管;构建日志已经刷出来但停住不走右支,归执行现场管。左支的钥匙在控制器配置,右支的钥匙在节点机器的进程现场,两边工具完全不同。
四、逐条排查展开
排队段:分清「没执行器空」和「没节点配得上」。 Waiting for next available executor 是节点配得上但都在忙——节点列表里看每个节点的执行器占用条,全满就是容量问题:要么等,要么把该节点的执行器数调大(别超过节点 CPU 核数),要么加节点。There are no nodes with the label 则是配置问题:Jenkinsfile 里的标签没有任何节点认领,永远排不上——对拍 Jenkinsfile 的 label 与节点配置页 Labels 字段,逐字符、大小写敏感。还有一种隐蔽的:节点在、标签也对,但节点被设成「仅运行绑定本节点的任务」,你的任务没绑定,照样排队。
执行段第一种:input 步骤在等人。 日志最后一行是 Input requested,构建页面上那个不显眼的「Proceed / Abort」按钮就是全部答案——很多团队的发版卡点设计如此,只是没人记得去点。Blue Ocean 界面里 input 步骤会有明显的等待标记。防复发:给 input 配超时,如 timeout(time: 1, unit: 'DAYS') { input ... },没人点就自动 Abort,不会挂一周占着执行器。
执行段第二种:命令真挂了,上节点看现场。 日志停在某条 sh 命令之后再无输出,别盯着页面猜——SSH 上对应节点,按进程树找:
# 在构建节点上,先找 Jenkins agent 拉起的进程树
ps aux | grep run-tests
# 看进程状态:D 状态 = 不可中断 IO 等待,常见挂死信号
ps -eo pid,stat,wchan:30,cmd | grep run-tests
# 需要时看线程栈
jstack <pid> # Java 进程
cat /proc/<pid>/stack 2>/dev/null进程状态是 D(不可中断睡眠)多半是 IO 挂死(NFS 掉线、磁盘故障);状态正常但 CPU 为 0 多半是死锁在等锁;CPU 100% 是活锁或死循环。确认后 kill 掉,构建会以失败告终——这好过永远挂着。根治要回到被测程序本身修死锁。
shell 阻塞读 stdin 是最冤的挂死。 脚本里调了带交互的命令(如某些 CLI 工具遇错时会问 yes/no),Jenkins 的 shell 没有 TTY,命令就永远等在那行输入上。特征:日志停在这条命令、节点上该进程 wchan 是 read。修法:给命令喂空输入 cmd < /dev/null,或找到命令的非交互参数(--yes、--non-interactive、--batch 之类)加上。新写的流水线脚本,凡是外部命令都默认 < /dev/null 是个好习惯。
节点负载打满是「集体龟速」。 同一节点上所有构建都变慢、但没一个报错——上节点 top 看 load average 与 CPU 占用,free -m 看内存是否吃满进了 swap,iostat 看磁盘 util%。执行器数配得比核数多、多个重任务挤在同一节点,是典型成因。处置:执行器数对齐核数、重任务用标签调度到专用节点、必要时给节点扩容。
超时兜底是卡死的最后一道保险。 没有超时的流水线,一个挂死可以占着执行器到天荒地老。两道闸都要配:整条流水线配 options { timeout(time: 30, unit: 'MINUTES') }(按正常时长的 3 倍定);单个步骤用 timeout 块包住;input 步骤单独配超时。没改 Jenkinsfile 条件的老任务,装 Build Timeout 插件在任务配置页统一兜底,还能配「超时后判 Abort 还是 Failure」与「卡住无输出多久判死」(No Activity 策略对「日志停住」类挂死特别有效)。
五、规范做法与预防
- timeout 是流水线标配:options 级总超时 + input 级确认超时 + 重步骤级局部超时,三层都配。
- 命令一律去交互:外部命令加非交互参数并
< /dev/null,杜绝 stdin 阻塞。 - 执行器数对齐节点核数:重任务贴标签调度到专用节点,不混跑。
- 队列长度进监控:排队超阈告警,容量问题在白天消化而不是凌晨卡住发版。
- 挂死现场要留证:杀进程前抓
ps、jstack、日志尾部,回填到问题单,根治靠被测程序修死锁。 - 构建时长基线:记录每个任务的正常时长,超时阈值按基线 3 倍定,定期复核。
这一篇在知识体系里的位置
本篇是 Jenkins 排错速查簇的运行时入口篇,定位「构建开始了但不结束」:连执行器都排不上且节点灰 offline 看 Jenkins 节点离线速查;构建被权限拦住直接失败看 Jenkins 权限不足速查;升级后构建行为异常看 Jenkins 插件版本不兼容速查。「先分排队段还是执行段 → 排队段查调度、执行段查现场 → 超时兜底防复发」这条主线对一切卡死类问题通用。
一句话总结
Jenkins 构建卡死先分两段:没进构建是排队段——Waiting for next available executor 查执行器占用与扩容,no nodes with the label 对拍标签;进了构建但日志停住是执行段——停在 Input requested 就是等人点确认(给 input 配超时),停在某条命令就 SSH 上节点用 ps/wchan/jstack 看进程是死锁、IO 挂死还是阻塞读 stdin(外部命令一律去交互加 < /dev/null)。根治靠修被测程序与调度配置,兜底靠三层 timeout 与 Build Timeout 插件——没有超时的流水线,一个挂死就能拖死整条交付线。