go实现定时任务
在 Go(Golang)中实现**定时任务(Scheduled Tasks / Cron Jobs)**,有几种常见的方法。以下是常用的几种方式和对应的代码示例:
---
## ✅ 一、使用 `time.Timer` 和 `time.Ticker`
适用于简单的周期性任务或单次延迟执行。
### 示例 1:单次定时任务(延迟执行)
```go
package main
import (
"fmt"
"time"
)
func main() {
fmt.Println("Start")
// 创建一个定时器,5秒后触发
timer := time.NewTimer(5 * time.Second)
<-timer.C // 等待定时器触发
fmt.Println("5 seconds later")
}
```
### 示例 2:周期性定时任务(Ticker)
```go
package main
import (
"fmt"
"time"
)
func main() {
ticker := time.NewTicker(2 * time.Second)
defer ticker.Stop()
for range ticker.C {
fmt.Println("Tick at", time.Now())
}
}
```
⚠️ 注意:`ticker` 需要手动 `Stop()`,否则会持续运行并占用资源。
---
## ✅ 二、使用 `time.AfterFunc` 实现延迟函数调用
适合只执行一次的延迟任务,并且可以取消。
```go
package main
import (
"fmt"
"time"
)
func main() {
fmt.Println("Start")
timer := time.AfterFunc(3*time.Second, func() {
fmt.Println("AfterFunc triggered")
})
// 可以取消 timer
// timer.Stop()
time.Sleep(5 * time.Second) // 保证主 goroutine 不退出
}
```
---
## ✅ 三、使用 `robfig/cron` 库(功能强大,推荐用于复杂场景)
这是一个广泛使用的第三方库,支持 cron 表达式。
### 安装:
```bash
go get github.com/robfig/cron/v3
```
### 示例代码:
```go
package main
import (
"fmt"
"github.com/robfig/cron/v3"
"time"
)
func main() {
c := cron.New()
// 每5秒执行一次
c.AddFunc("*/5 * * * * *", func() {
fmt.Println("cron job executed at", time.Now())
})
c.Start()
// 阻塞主线程不退出
select {}
}
```
### Cron 表达式格式(共6位):
| 字段名 | 允许值 |
|----------------|-------------------|
| 秒 | 0-59 |
| 分 | 0-59 |
| 小时 | 0-23 |
| 日期 | 1-31 |
| 月份 | 1-12 或 JAN-DEC |
| 星期几 | 0-6 或 SUN-SAT |
> 更多文档:[https://pkg.go.dev/github.com/robfig/cron/v3](https://pkg.go.dev/github.com/robfig/cron/v3)
---
## ✅ 四、结合 Goroutine + Channel 实现更灵活控制
你可以封装一个结构体来管理定时任务的启动、停止等操作。
```go
package main
import (
"fmt"
"time"
)
type Scheduler struct {
stopChan chan struct{}
}
func NewScheduler() *Scheduler {
return &Scheduler{
stopChan: make(chan struct{}),
}
}
func (s *Scheduler) Start(interval time.Duration, task func()) {
go func() {
ticker := time.NewTicker(interval)
defer ticker.Stop()
for {
select {
case <-ticker.C:
task()
case <-s.stopChan:
fmt.Println("Scheduler stopped.")
return
}
}
}()
}
func (s *Scheduler) Stop() {
close(s.stopChan)
}
func main() {
scheduler := NewScheduler()
scheduler.Start(2*time.Second, func() {
fmt.Println("Task executed at", time.Now())
})
// 运行一段时间后停止
time.Sleep(10 * time.Second)
scheduler.Stop()
time.Sleep(2 * time.Second) // 让日志输出可见
}
```
---
## ✅ 五、在 Web 应用中使用定时任务(如 Gin、Echo)
如果你是在构建一个 Web 应用(比如使用 Gin),可以在程序启动后异步运行定时任务。
```go
package main
import (
"github.com/gin-gonic/gin"
"time"
)
func startBackgroundJob() {
ticker := time.NewTicker(5 * time.Second)
go func() {
for range ticker.C {
// 执行后台任务逻辑
println("Background job running...")
}
}()
}
func main() {
r := gin.Default()
startBackgroundJob()
r.GET("/", func(c *gin.Context) {
c.String(200, "Hello from Gin with background job!")
})
r.Run(":8080")
}
```
---
## 🔚 总结
| 方法 | 适用场景 | 是否推荐 |
|--------------------|------------------------------------|----------|
| `time.Timer` | 单次延迟任务 | ✅ |
| `time.Ticker` | 周期性任务 | ✅ |
| `time.AfterFunc` | 延迟执行一个函数 | ✅ |
| `robfig/cron` | 支持 cron 表达式的复杂调度任务 | ⭐ 推荐 |
| 自定义 scheduler | 控制启动/停止、集成到项目中 | ✅ |
| Web 框架中运行任务 | Web 应用中需要后台定时逻辑 | ✅ |
---
如果你有具体的业务需求(比如:每天凌晨执行某个任务、任务持久化、分布式定时任务等),欢迎继续提问,我可以提供更详细的实现方案!