「Jenkins」- 周期性构建/定时执行作业(学习笔记,翻译)

更新日期:2020年10月04日

问题描述

在 Jenkins 中,我们需要周期性构建,即定时执行作业,比如每隔 15 分钟执行构建。

通过 Build Triggers / Build periodically 实现(针对每个作业的单独设置)

该笔记将记录:Build periodically 的配置方法(实际是对帮助手册的翻译,“帮助手册”是指在 Build periodically 后的“问号按钮”)

学习笔记(文档翻译)

该字段(Build periodically)的语法与 Cron 类似,但是有轻微的不同。明确地说,每行有五个字段,使用 SPACE 或 TAB 分隔:
1)MINUTE,Minutes within the hour (0–59)
2)HOUR,The hour of the day (0–23)
3)DOM,The day of the month (1–31)
4)MONTH,The month (1–12)
5)DOW,The day of the week (0–7) where 0 and 7 are Sunday.

在单个字段上,可以指定多个值(操作符),格式如下(以下按照优先级排序):
1)*,指定多个有效值;
2)M-N,指定某个范围内的值;
3)M-N/X*/X,在特定范围(M-N)或者全部有效值(*)内,间隔 X 的所有值;
4)A,B,...,Z,罗列出多个值;

使用 H 符号

为了平均 Jenkins 的负载,建议使用 H 符号。比如说,使用 0 0 * * * 将导致 Jenkins 在半夜集中执行定时任务,但是使用 H H * * * 将保证任务每天执行一次,但是不会集中执行。

符号 H 还支持使用范围。比如说,H H(0-7) * * * 表示在 00:00 - 07:59 内的某个时间。在符号 H 中,我们还可以使用间隔(无论是否使用范围)

可以将 H 符号视为某个范围内的随机值,但实际上它是作业名称的哈希值,而不是随机函数,因此该值对于任何给定项目均保持稳定(即对于特定作业的执行时间是固定的)

注释符号

空行或者井号(#)开始的行将被忽略。

使用别名

除此之外,还可以使用 @yearly, @annually, @monthly, @weekly, @daily, @midnight, @hourly 等别名,他们依旧使用哈希值的方式进行平均均衡。比如说,@hourlyH * * * * 相同,表示在小时内的任意时间。@midnight 表示 12:00 AM - 2:59 AM 的某个时间。

简单示例

# 每十五分钟执行一次(可能是 :07, :22, :37, :52)
H/15 * * * *

# 在前半个小时内,每十分钟执行一次(执行三次,可能是 :04, :14, :24)
H(0-29)/10 * * * *

# 在周一到周五内,9:45 AM - 4:45 PM,每两小时执行一次
# 09:45 11:45 01:45 03:45
45 9-16/2 * * 1-5

# 在周一到周五内,9 AM - 5 PM,每两小时执行一次(可能是 10:38 AM, 12:38 PM, 2:38 PM, 4:38 PM)
H H(9-16)/2 * * 1-5

# 除了十二月,每个月的一号与十五号,执行一次
H H 1,15 1-11 *

指定时区

为 Jenkins master 的 JVM 设置的时区决定定时任务执行时间。但是可以通过 TZ= 进行设置(添加在 Build periodically 字段的第一行),例如:

TZ=Europe/London
# This job needs to be run in the morning, London time
H 8 * * *
# Butlers do not have a five o'clock, so we run the job again
H(0-30) 17 * * *

注意事项

对于 DOM 字段,由于月份长度是变换的,因此较短周期(比如 H/3 或 */3 设置)的执行并不稳定。比如说,*/3 将在 1st, 4th, …31st 执行,然后从下个月的第二天开始执行。对于哈希时间(使用 H 符号),将在 1-28 内选择,因此 H/3 将在月底产生 3 - 6 天的时间间隙(因为 1-28,而下个月可能是 1 或 3 开始。对于本月 31 天的月份:下个月从 3 号开始,这就是 6 天间隙;下月从 1 号开始,则是 3 天间隙)。较长周期的间隔长度也不稳定,但是效果可能相对不太明显。

# 10/04/2020 在我们的使用过程中,我们发现时间设置 H/1 * * * * 也是存在问题的。如果使用 */1 * * * * 会产生如下提示(或者其他 */X 都会建议使用 H 符号):

Do you really mean "every minute" when you say "*/1 * * * *"? Perhaps you meant "H * * * *" to poll once per hour

原始手册

This field follows the syntax of cron (with minor differences). Specifically, each line consists of 5 fields separated by TAB or whitespace:

MINUTE HOUR DOM MONTH DOW

MINUTE	Minutes within the hour (0–59)
HOUR	The hour of the day (0–23)
DOM	The day of the month (1–31)
MONTH	The month (1–12)
DOW	The day of the week (0–7) where 0 and 7 are Sunday.

To specify multiple values for one field, the following operators are available. In the order of precedence,

    * specifies all valid values
    M-N specifies a range of values
    M-N/X or */X steps by intervals of X through the specified range or whole valid range
    A,B,...,Z enumerates multiple values

To allow periodically scheduled tasks to produce even load on the system, the symbol H (for “hash”) should be used wherever possible. For 
example, using 0 0 * * * for a dozen daily jobs will cause a large spike at midnight. In contrast, using H H * * * would still execute each 
job once a day, but not all at the same time, better using limited resources.

The H symbol can be used with a range. For example, H H(0-7) * * * means some time between 12:00 AM (midnight) to 7:59 AM. You can also use 
step intervals with H, with or without ranges.

The H symbol can be thought of as a random value over a range, but it actually is a hash of the job name, not a random function, so that the 
value remains stable for any given project.

Beware that for the day of month field, short cycles such as */3 or H/3 will not work consistently near the end of most months, due to variable 
month lengths. For example, */3 will run on the 1st, 4th, …31st days of a long month, then again the next day of the next month. Hashes are 
always chosen in the 1-28 range, so H/3 will produce a gap between runs of between 3 and 6 days at the end of a month. (Longer cycles will 
also have inconsistent lengths but the effect may be relatively less noticeable.)

Empty lines and lines that start with # will be ignored as comments.

In addition, @yearly, @annually, @monthly, @weekly, @daily, @midnight, and @hourly are supported as convenient aliases. These use the hash 
system for automatic balancing. For example, @hourly is the same as H * * * * and could mean at any time during the hour. @midnight actually 
means some time between 12:00 AM and 2:59 AM.

Examples:

# every fifteen minutes (perhaps at :07, :22, :37, :52)
H/15 * * * *
# every ten minutes in the first half of every hour (three times, perhaps at :04, :14, :24)
H(0-29)/10 * * * *
# once every two hours at 45 minutes past the hour starting at 9:45 AM and finishing at 3:45 PM every weekday.
45 9-16/2 * * 1-5
# once in every two hours slot between 9 AM and 5 PM every weekday (perhaps at 10:38 AM, 12:38 PM, 2:38 PM, 4:38 PM)
H H(9-16)/2 * * 1-5
# once a day on the 1st and 15th of every month except December
H H 1,15 1-11 *

# Time zone specification

Periodic tasks are normally executed at the scheduled time in the time zone of the Jenkins master JVM (currently Asia/Shanghai). This 
behavior can optionally be changed by specifying an alternative time zone in the first line of the field. Time zone specification starts 
with TZ=, followed by the ID of a time zone.

Complete example of a schedule with a time zone specification:

    TZ=Europe/London
    # This job needs to be run in the morning, London time
    H 8 * * *
    # Butlers do not have a five o'clock, so we run the job again
    H(0-30) 17 * * *
  
The supported time zones depend on the Java runtime Jenkins is running on. The list of supported time zone IDs on this instance is: 
...

参考文献

cron - How do I schedule jobs in Jenkins? - Stack Overflow
jenkins/help-spec.jelly at master · jenkinsci/jenkins


ToC

问题描述

学习笔记(文档翻译)

使用 H 符号

注释符号

使用别名

简单示例

指定时区

注意事项

原始手册

参考文献