Jenkins 重复触发构建速查:webhook 双注册、轮询叠加钩子与并发互踩
更新时间:2026-10-24。FAQ 速查页,面向「push 一次、流水线跑两条」「两条构建同时改同一个工作区、结果互相覆盖」的同学。Jenkins 重复触发的本质是触发通道只有一条才该响、实际却响了两条:webhook 注册了两份(手动配一份、插件又自动配一份),或 SCM 轮询与 webhook 同时开着,或 multibranch 的分支索引在 webhook 之外又补了一枪。重复触发本身不报错,它的危害在第二步:两条构建并发跑、共享工作区或共享部署目标时互相踩踏,日志里留下莫名其妙的文件状态错乱。病因收敛在六根轴上:webhook 重复注册、轮询与钩子双通道并存、multibranch 索引触发叠加、Parameterized Trigger 类下游任务误挂、并发构建互踩(disableConcurrentBuilds 缺失)、lock 资源或 abort 策略没配。把「谁在触发」与「并发时怎么排队」两个问题分开解,基本必中。如果触发正常但构建里变量取不到,转 Jenkins 环境变量不生效速查。
本文要回答的问题
- 一次 push 触发了两条构建,第二条的触发原因写的是什么?
- webhook 在仓库后台配了一份,为什么 Jenkins 还会自己注册一份?
- 关了轮询还会被触发,哪里还有第二条通道?
- 两条构建同时跑同一个 job,工作区文件怎么会互相覆盖?
- 想保留并发但部署阶段要互斥,怎么配?
一、典型现象与触发线索
重复触发的现场证据藏在构建列表与触发原因里(控制器地址以 jenkins.example.com 占位,路径以 /proj/demo 占位):
# 现场一:构建列表里同一次提交出现两条相邻构建
#47 Started by GitLab push by zhangsan 2 min ago
#48 Started by GitLab push by zhangsan 2 min ago
# 现场二:两条构建的触发原因不同——双通道的铁证
#47 Started by GitLab push by zhangsan
#48 Started by an SCM change
# 现场三:并发互踩的工作区错乱日志
+ mvn package
[ERROR] /proj/demo/target/classes/com/demo/App.class
file has changed during the build读法:两条构建的「Started by」相同说明同一通道重复注册;不同(一条 push、一条 SCM change)说明 webhook 与轮询双通道并存;Started by branch indexing 则是 multibranch 的索引补枪。先分类再动手。
二、病因处置速查表
| 报错现象 / 场景 | 可能原因 | 快速验证 | 处置 |
|---|---|---|---|
| 两条构建 Started by 都是 push | webhook 在仓库侧注册了两份 | 仓库 Webhooks 页数条数 | 去重只留一条,插件自动注册的留给插件 |
| 一条 push 一条 SCM change | 轮询与 webhook 同时开着 | 看 job 配置触发器段 | 二选一,推荐留 webhook 关轮询 |
| Started by branch indexing | multibranch 索引与 webhook 叠加 | 看 multibranch 的触发策略 | 索引策略改为只 webhook 或调整 scan 周期 |
| 下游任务莫名多跑 | Parameterized Trigger 误挂多份 | 看 job 的构建后操作 | 清掉重复 downstream 配置 |
| 两条构建互相改对方文件 | 并发构建共享工作区 | 看是否同一 node 同一 workspace | 开 disableConcurrentBuilds 或隔离工作区 |
| 排队堆积但还会并发到部署 | 部署段没互斥 | 看部署步骤是否有 lock | 用 lock 插件圈住部署临界区 |
三、排查决策图
下面这张图是标准排查路线,颜色按角色区分:红是现象入口与命中的根因,蓝是排查动作,绿是通过分支,橙是修复动作,紫是防复发沉淀。
读这张图抓分水岭:第一步永远是比较两条构建的触发原因文本,它直接把问题劈成两半——触发源重复(通道问题,走左支)与触发正常但并发互踩(编排问题,走右支)。多数人上来就删 webhook,删对了通道但互踩还在;两类病因要分别修。
四、逐条排查展开
webhook 重复注册是双触发的头号来源。 典型场景:管理员在 GitLab/Gitee 后台手动配了一条 webhook 指向 jenkins.example.com/project/demo,而 GitLab 插件在 job 里勾了「自动注册 webhook」又配了一份——同一次 push 收到两个 POST,Jenkins 起两条构建。验证:到仓库的 Webhooks 设置页数条数、看每条的历史请求记录。处置:只留一条;如果插件管理注册,就删掉手动那条,避免日后 URL 变了手动那条成孤儿。
轮询与钩子并存是最古老的配方。 早期配的 pollSCM('H/5 * * * *') 没删,后来又接了 webhook——push 时 webhook 立刻触发一条,下一次轮询发现「SCM 有变化」又补一条。验证就看触发原因里有没有 Started by an SCM change。处置:有 webhook 就关轮询(触发器里去掉 Poll SCM);网络隔离收不到 webhook 的环境才保留轮询,且周期不要太密。
multibranch 的索引触发常被忽略。 Multibranch Pipeline 的「Scan Repository」除了响应 webhook,还会按周期做分支索引(branch indexing),索引发现新提交也会触发构建。症状是触发原因写 Started by branch indexing。处置:在 multibranch 配置里把触发策略调成以 webhook 为准,或拉长 scan 周期让它只兜底;别指望删了 webhook 侧配置就能止住索引触发。
下游触发链也会复制构建。 用 Parameterized Trigger 之类插件挂了「构建后触发下游」,而下游 job 自己又配了 webhook——上游完成触发一次、push 又触发一次。画一张触发关系图:谁挂谁、谁监听仓库,一眼能看出环路与重复边。处置:下游任务只保留一种入口,触发关系收敛到单链。
并发互踩要用 disableConcurrentBuilds 或隔离工作区。 同 job 默认允许并发,两条构建在同一 node 上共用 /proj/demo 工作区时,第二条 git clean -fdx 会把第一条的中间产物清掉。Declarative 里加 options { disableConcurrentBuilds() } 让同 job 排队;确实要并发加速的,用 ws() 或自定义工作区目录按构建号隔离。
部署等临界区用 lock 圈住,abort 处理积压。 构建可以并发、部署不能并发的场景,用 Lockable Resources 插件:lock('deploy-prod') { sh './deploy.sh' },资源粒度的互斥比整 job 禁并发更精细。另外积压场景配 disableConcurrentBuilds(abortPrevious: true) 让新提交直接中止旧构建,只部署最新状态,省时又避免乱序部署。
五、规范做法与预防
- 触发通道单源化:每个仓库到 Jenkins 只保留一条触发链路(优先 webhook),轮询只作隔离网段的兜底。
- webhook 归属明确:插件自动注册的由插件管,手动注册的进仓库配置审计,两类不并存。
- 并发策略进模板:job 模板默认
disableConcurrentBuilds,部署段默认lock,需要并发时显式声明理由。 - 触发原因纳入巡检:定期抽查高频构建 job 的 Started by 分布,出现双通道字样即修。
- multibranch 策略写明:scan 周期与 webhook 的分工写进项目 README,新人不再踩索引触发。
- 变更评审带触发面:新增下游触发、改 webhook URL 时,同步检查有没有造出第二条通道。
这一篇在知识体系里的位置
本篇是 Jenkins 排错速查簇的「触发编排」入口:触发正常了但构建里变量取不到看 Jenkins 环境变量不生效速查;webhook 推过来 Jenkins 却没反应(连接层面)看 Jenkins 连接被拒速查;并发构建把内存句柄打爆看 Jenkins 内存句柄耗尽速查;同簇还有 Jenkinsfile 语法错误速查、Jenkins 构建超时卡死速查。「先比对触发原因文本、把触发源重复与并发互踩分开修」这条主线对一切事件驱动 CI 系统通用。
一句话总结
Jenkins 重复触发先看两条构建的 Started by:同是 push 是 webhook 注册了两份(仓库后台去重),一条 push 一条 SCM change 是轮询与钩子并存(关轮询留钩子),branch indexing 是 multibranch 索引补枪(调触发策略)。触发修好后并发互踩单独修:同 job 默认 disableConcurrentBuilds,要并发就按构建号隔离工作区,部署临界区用 lock 圈住,积压场景配 abortPrevious: true。触发通道单源化与并发基线进模板后,这类问题基本绝迹。