goCron 的 AddFunc 函数用于添加一个定时执行的函数。定时时间的设置非常灵活,主要通过 cron.ParseStandard 或 cron.Parse 函数来解析一个 cron 表达式。
下面我们详细讲解如何设置定时时间:
goCron 的定时时间就是通过 cron 表达式 来定义的。cron 表达式是一种字符串,用于描述一个在特定时间执行的计划。它通常由五个或六个字段组成,从左到右依次代表:
* 秒 (Second)
* 分 (Minute)
* 时 (Hour)
* 日 (Day of Month)
* 月 (Month)
* 日 (Day of Week) (可选,如果包含则为六个字段)
字段的取值范围:
* 秒 (Second): 0-59
* 分 (Minute): 0-59
* 时 (Hour): 0-23
* 日 (Day of Month): 1-31
* 月 (Month): 1-12 (或 JAN-DEC)
* 日 (Day of Week): 0-6 (0 为星期日,或 SUN-SAT)
特殊字符:
* * (星号): 匹配所有可能的值。例如,在“分”字段中使用 * 表示每分钟。
* , (逗号): 分隔列表。例如,1,3,5 在“小时”字段表示 1 点、3 点、5 点。
* - (连字符): 表示范围。例如,9-17 在“小时”字段表示从 9 点到 17 点。
* / (斜杠): 表示步长。例如,*/15 在“分”字段表示每 15 分钟。0/5 在“秒”字段表示从 0 秒开始,每 5 秒一次。
AddFunc 函数签名
goCron 的 AddFunc 函数通常有以下签名:go
func (c *Cron) AddFunc(spec string, cmd func()) (EntryID, error)
* spec: 这是cron 表达式字符串。
* cmd: 这是你想要定时执行的函数。
你可以通过 cron.ParseStandard 或 goCron 提供的其他解析函数来解析 cron 表达式。cron.ParseStandard 是最常用的,它解析符合标准的 cron 格式。
以下是一些常见的定时时间设置示例:
1. 每分钟执行一次:
go
spec := "* * * * *" // 秒 分 时 日 月 (星期日)
cron.AddFunc(spec, func() {
fmt.Println("每分钟执行一次")
})
* 注意: 默认情况下,goCron 的 cron 表达式是 “秒 分 时 日 月” 的五字段格式。如果你需要包含秒,可以使用六字段格式。
2. 每小时的第 30 分钟执行一次:
go
spec := "0 30 * * *" // 秒 分 时 日 月
cron.AddFunc(spec, func() {
fmt.Println("每小时的第 30 分钟执行一次")
})
3. 每天的 0 点 0 分 0 秒执行一次:
go
spec := "0 0 0 * * *" // 秒 分 时 日 月 (星期日)
cron.AddFunc(spec, func() {
fmt.Println("每天的午夜执行一次")
})
4. 每周一的上午 9 点 0 分 0 秒执行一次:
go
spec := "0 0 9 * * 1" // 秒 分 时 日 月 (星期一)
cron.AddFunc(spec, func() {
fmt.Println("每周一上午 9 点执行一次")
})
5. 每月 1 号的 10 点 15 分 30 秒执行一次:
go
spec := "30 15 10 1 * *" // 秒 分 时 日 月 (星期日)
cron.AddFunc(spec, func() {
fmt.Println("每月 1 号的 10 点 15 分 30 秒执行一次")
})
6. 每 5 秒执行一次:
go
spec := "*/5 * * * * *" // 秒 分 时 日 月 (星期日)
cron.AddFunc(spec, func() {
fmt.Println("每 5 秒执行一次")
})
7. 在 9 点到 17 点之间,每 10 分钟执行一次:
go
spec := "0 */10 9-17 * * *" // 秒 分 时 日 月 (星期日)
cron.AddFunc(spec, func() {
fmt.Println("在 9 点到 17 点之间,每 10 分钟执行一次")
})
8. 在工作日 (周一到周五) 的早上 8 点 30 分执行一次:
go
spec := "0 30 8 * * 1-5" // 秒 分 时 日 月 (星期一到星期五)
cron.AddFunc(spec, func() {
fmt.Println("工作日早上 8 点 30 分执行一次")
})
cron.ParseStandard
AddFunc 函数内部会调用 cron.ParseStandard 来解析 spec 字符串。你可以直接使用 cron.ParseStandard 来验证你的 cron 表达式是否有效,或者在 AddFunc 之前进行解析。go
package main
import (
"fmt"
"log"
"time"
"github.com/robfig/cron/v3"
)
func main() {
c := cron.New() // 创建一个新的 Cron 实例
// --- 示例 1: 每分钟执行一次 ---
spec1 := "* * * * *"
_, err1 := c.AddFunc(spec1, func() {
fmt.Println("【任务1】每分钟执行一次")
})
if err1 != nil {
log.Fatalf("添加任务1失败: %v", err1)
}
// --- 示例 2: 每小时的第 30 分钟执行一次 ---
spec2 := "0 30 * * *"
_, err2 := c.AddFunc(spec2, func() {
fmt.Println("【任务2】每小时的第 30 分钟执行一次")
})
if err2 != nil {
log.Fatalf("添加任务2失败: %v", err2)
}
// --- 示例 3: 每天的 0 点 0 分 0 秒执行一次 ---
spec3 := "0 0 0 * * *" // 包含秒
_, err3 := c.AddFunc(spec3, func() {
fmt.Println("【任务3】每天的午夜执行一次")
})
if err3 != nil {
log.Fatalf("添加任务3失败: %v", err3)
}
// --- 示例 4: 每 5 秒执行一次 ---
spec4 := "*/5 * * * * *" // 包含秒
_, err4 := c.AddFunc(spec4, func() {
fmt.Println("【任务4】每 5 秒执行一次")
})
if err4 != nil {
log.Fatalf("添加任务4失败: %v", err4)
}
// --- 示例 5: 每 10 分钟执行一次 ---
spec5 := "0 */10 * * *"
_, err5 := c.AddFunc(spec5, func() {
fmt.Println("【任务5】每 10 分钟执行一次")
})
if err5 != nil {
log.Fatalf("添加任务5失败: %v", err5)
}
// --- 示例 6: 周一到周五的早上 8 点 30 分执行一次 ---
spec6 := "0 30 8 * * 1-5" // 1-5 代表周一到周五
_, err6 := c.AddFunc(spec6, func() {
fmt.Println("【任务6】工作日早上 8 点 30 分执行一次")
})
if err6 != nil {
log.Fatalf("添加任务6失败: %v", err6)
}
c.Start() // 启动 cron 调度器
// 让主 goroutine 保持运行,否则 cron 调度器会停止
select {}
}
1. Cron 表达式的字段顺序: 始终记住字段的顺序是 秒 分 时 日 月 (星期日)。
2. 秒字段: 默认的 goCron 调度器是每秒启动一次的。因此,如果你需要精确到秒的任务,cron 表达式需要包含秒字段。如果你的 cron 表达式只有 5 个字段 (* * * * *),那么它将被解析为 分 时 日 月 (星期日),而秒字段会被隐式设置为 0。
3. 时区: goCron 默认使用服务器的本地时区。如果你需要指定时区,可以在创建 Cron 实例时使用 cron.New(cron.WithLocation(location)),其中 location 是一个 *time.Location 对象,例如 time.LoadLocation("Asia/Shanghai")。
4. 错误处理: AddFunc 会返回一个 error,用于指示 cron 表达式是否解析失败。务必检查这个错误。
5. 启动调度器: 添加完任务后,你需要调用 c.Start() 来启动 cron 调度器。
6. 保持主 Goroutine 运行: 如果你的主 goroutine 结束,cron 调度器也会停止。通常会使用 select {} 来让主 goroutine 永久阻塞,从而保持程序运行。
通过掌握 cron 表达式的语法和 goCron 的 AddFunc 函数,你可以非常灵活地设置各种定时任务。