Jenkins 定时构建不触发速查:cron 语法、时区、pollSCM 与任务禁用
更新时间:2026-10-24。FAQ 速查页,面向「配了定时触发器,到了点构建列表却毫无动静」的同学。这类问题最折磨人的地方是没有报错——没有红叉、没有异常栈,只有一片安静。Jenkins 定时构建不触发的本质是「调度器根本没把你排进队列」或「排进去了但被判定不该跑」:病因收敛在五根轴上——cron 语法写错或 H 分散符理解偏差、控制器系统时区与任务声明时区不一致、pollSCM 是「轮询变更」而不是「定时构建」、任务被禁用或被静默期/并发设置拦截、以及触发器配置保存后没真正生效。顺一遍基本必中。如果构建触发了但卡在队列里排不到执行器,那是另一个问题,转 Jenkins 节点离线速查。
本文要回答的问题
- cron 表达式写错了,Jenkins 为什么不报错也不跑?
H到底什么意思,为什么我的任务不在整点跑?- 控制器时区和任务时区不一致,定时会偏多久?
- 配了 pollSCM,为什么代码有提交还是不构建?
- 任务配置页明明有触发器,为什么像不存在一样?
一、报错原文与典型现象
定时类问题的「报错」分散在配置校验提示、系统日志与构建历史的「缺席」里(控制器地址以 jenkins.example.com 占位,任务路径以 /proj/demo 占位):
# 配置页 cron 输入框下方的校验提示
Invalid input: "0 9 * *": line 1:1
unexpected end of line.
# 或
Do you really mean "every minute" when
you say "* * * * *"? Perhaps you meant "H * * * *"# 系统日志里的调度痕迹(管理 → 系统日志)
Polling started on ... for job proj/demo
No changes detected. Done.
# 有这条说明 pollSCM 在跑,只是判定无变更# 典型现象:构建历史里「该出现的构建」整段缺席
# 每天 9 点的定时构建,连续三天构建编号断档
# 任务页顶部显示:This project is currently disabled读现象先分两类:配置页有红色校验提示是语法层的问题,改表达式就行;配置合法但构建缺席是调度层的问题,要去查时区、pollSCM 语义与任务状态。两类修法互不相干,先定性。
二、病因处置速查表
| 报错现象 / 场景 | 可能原因 | 快速验证 | 处置 |
|---|---|---|---|
| 配置页提示 Invalid input | cron 段数或字段写错 | 对照五段式逐段检查 | 按「分 时 日 月 周」补全五段 |
| 任务不在预期的整点跑 | 用了 H 分散符,调度被哈希错开 | 看构建实际触发时刻的规律 | 要固定时刻用数字,要削峰保留 H |
| 定时偏差整好几个小时 | 控制器时区与任务声明时区不符 | 系统管理 → 系统信息查 user.timezone | cron 前加 TZ= 声明,或统一控制器时区 |
| pollSCM 配了但提交不构建 | 轮询无变化判定或 SCM 配置不通 | 系统日志看 Polling 记录 | 修 SCM 凭据;要定时构建改用 cron 触发器 |
| 构建历史整段缺席且无痕迹 | 任务被禁用 | 任务页顶部找 disabled 提示 | Enable 恢复,查是谁何时禁用的 |
| 改动触发器后毫无反应 | 保存未生效或被并发/静默期拦 | 重新保存并观察下一周期 | Apply 后手动触发一次验证链路 |
三、排查决策图
下面这张图是标准排查路线,颜色按角色区分:红是报错入口与命中的根因,蓝是排查动作,绿是通过分支,橙是修复动作,紫是防复发沉淀。
读这张图抓分水岭:配置页输入框下方有红色提示走左支,纯粹是表达式没写对;配置干干净净但构建缺席走右支,去系统日志找 Polling 痕迹、去系统信息核对时区。Jenkins 对非法 cron 只在配置页提示、不在运行时告警——保存前那一眼校验提示是唯一的拦截网。
四、逐条排查展开
cron 语法:五段一个都不能少。 Jenkins 沿用标准 cron 的「分 时 日 月 周」五段式,少一段、多一段、字段越界都会在输入框下方给出红色提示。最容易踩的三个坑:一是把「每天 9 点」写成 0 9 * *(四段,缺周日字段);二是把「每小时」写成 * * * * *(每分钟,调度器会友情提示你是不是写错了);三是以为周字段从周一开始(0 和 7 都是周日)。改完看输入框下方出现绿色的下次预计触发时间才算数。
H 是削峰分散符不是占位符。 H 9 * * * 的含义是「9 点这个小时内的某个分钟,由任务名哈希决定」——目的是让几百个任务不要都挤在整点同时开火。代价是你的任务不在 9:00 准点跑,可能落在 9:17 或 9:43,且同一任务每次的时刻基本固定(哈希稳定)。要准点触发(比如掐着外部系统数据就绪的时刻)就老老实实写 0 9 * * *;只是「每天跑一次」的批任务建议保留 H,全公司任务都写整点是控制器周期性卡顿的常见根因。H/15 * * * * 表示「每 15 分钟档里哈希一个点」,不是严格每 15 分钟。
时区:cron 按控制器本地时间走,除非显式声明。 任务 cron 默认使用控制器 JVM 的时区(系统管理 → 系统信息里搜 user.timezone 能看到)。控制器部署在海外机房、团队在东八区,「每天 9 点跑」就变成了北京时间下午或凌晨。处置两条路:任务级在 cron 表达式前加一行 TZ=Asia/Shanghai,该任务按声明时区走;控制器级在启动参数里统一设时区,适合全站同一批用户的场景。改完时区要重启或重新保存任务才生效。
pollSCM 是「轮询变更」不是「定时构建」。 这是最经典的语义误会:H/5 * * * * 配在 Poll SCM 里,含义是「每 5 分钟问一次仓库有没有新提交,有才构建」——没提交就什么都不跑,这是特性不是故障。验证方式:系统日志里找该任务的 Polling 记录,「No changes detected」说明轮询正常工作。三个真故障点:一是 SCM 凭据失效导致轮询直接报错(日志里会有异常栈);二是分支通配配错,轮询盯的分支不是你提交的那个;三是想要「无论有无变更都定时跑」,那应该配 Build periodically(构建触发器里的定时构建),不是 pollSCM。两个触发器可以同时存在,语义互不替代。
任务被禁用:没有任何告警的沉默杀手。 任务页顶部「This project is currently disabled」、侧边栏按钮从「立即构建」变成「Enable」——处于禁用状态的任务,定时器、Webhook、上游触发全部静默失效,构建历史里该出现的构建整段缺席。常见于排障时临时禁用后忘了恢复。处置:点 Enable 恢复,然后查任务配置历史(装了 Job Config History 插件的话)确认是谁在什么时候禁用的,避免同类事故重演。
保存生效与并发拦截的边角情况。 偶发场景:改了触发器但页面没真正 Apply(浏览器缓存或会话过期),配置没落盘;或任务配了「禁止并发构建」而上一轮构建跑了整夜没结束,新周期被跳过;或静默期(quiet period)设得过长,连续触发被合并推迟。这类问题的共性是「配置看着对、日志没痕迹」,处置三板斧:重新打开配置页确认值真的保存了、手动触发一次验证整条链路、把该任务下一周期的预计触发时间与实际触发时间对表。
五、规范做法与预防
- 保存前看校验提示:cron 输入框下方的红/绿提示是唯一拦截网,绿色下次触发时间出现才算配好。
- 批任务用 H 削峰:无准点要求的定时任务统一
H分散,整点只留给有外部依赖的少数任务。 - 时区显式声明:跨地域团队在 cron 前写
TZ=,不依赖控制器默认值。 - pollSCM 与定时构建分清:要「有变更才跑」配 Poll SCM,要「到点就跑」配 Build periodically,选型写进任务模板注释。
- 禁用操作留痕:临时禁用任务必须在工单里登记恢复时间,或干脆用「冻结触发器」类插件而不是 Disable。
- 定时任务定期对账:每月抽查关键定时任务的「应触发次数 vs 实际构建次数」,缺席即告警。
这一篇在知识体系里的位置
本篇是 Jenkins 排错速查簇的调度入口篇,定位「触发器与定时」:定时触发正常但构建排队不动看 Jenkins 节点离线速查;触发后构建偶发失败、时好时坏看 Jenkins 构建偶发失败速查;cron 触发时间与任务声明差整点怀疑配置被改看 Jenkins 配置解析失败速查。「配置页校验定语法层、系统日志 Polling 定调度层」这条主线对一切「该跑没跑」类问题通用。
一句话总结
Jenkins 定时构建不触发没有报错可贴,按两层排查:配置页有红色校验提示是语法层——cron 必须「分 时 日 月 周」五段齐全,H 是哈希削峰符不是整点占位符;配置合法但构建缺席是调度层——查控制器 user.timezone 与任务 TZ 声明、分清 pollSCM(无变更不构建)与 Build periodically(到点就跑)、确认任务没被禁用或静默期拦截。保存前看绿色下次触发时间、批任务统一 H 分散、禁用操作留痕,定时类问题基本绝迹。