任务调度
youlai-gin 支持定时任务调度,实现异步任务和定时处理。
定时任务
1. 基于 Cron
go
import "github.com/robfig/cron/v3"
// pkg/scheduler/scheduler.go
type Scheduler struct {
cron *cron.Cron
}
func NewScheduler() *Scheduler {
return &Scheduler{
cron: cron.New(cron.WithSeconds()),
}
}
func (s *Scheduler) Start() {
s.cron.Start()
}
func (s *Scheduler) Stop() {
s.cron.Stop()
}
// 添加任务
func (s *Scheduler) AddJob(spec string, job cron.Job) error {
_, err := s.cron.AddJob(spec, job)
return err
}2. 任务定义
go
// internal/system/job/clean_logs.go
package job
type CleanLogsJob struct {
logService *service.LogService
}
func (j *CleanLogsJob) Run() {
// 清理30天前的日志
j.logService.DeleteBefore(time.Now().AddDate(0, 0, -30))
}3. 注册任务
go
// main.go
func initScheduler() *scheduler.Scheduler {
s := scheduler.NewScheduler()
// 每天凌晨2点清理日志
s.AddJob("0 0 2 * * *", &job.CleanLogsJob{
logService: service.NewLogService(),
})
// 每5分钟检查过期会话
s.AddJob("0 */5 * * * *", &job.SessionCheckJob{})
s.Start()
return s
}Cron 表达式
秒 分 时 日 月 周
* * * * * *
示例:
"0 0 2 * * *" # 每天凌晨2点
"0 */5 * * * *" # 每5分钟
"0 0 9-17 * * 1-5" # 工作日9-17点每小时
"0 30 23 * * *" # 每天23:30异步任务
go
// 使用 goroutine + channel
type TaskQueue struct {
tasks chan func()
}
func NewTaskQueue(size int) *TaskQueue {
q := &TaskQueue{
tasks: make(chan func(), size),
}
go q.worker()
return q
}
func (q *TaskQueue) worker() {
for task := range q.tasks {
task()
}
}
func (q *TaskQueue) Submit(task func()) {
q.tasks <- task
}任务状态持久化
go
// 存储到数据库
type JobLog struct {
ID int64 `gorm:"primaryKey"`
JobName string `gorm:"size:100"`
Status string `gorm:"size:20"` // running/success/failed
StartTime time.Time
EndTime time.Time
Message string `gorm:"type:text"`
}
// 任务执行时记录
func (j *CleanLogsJob) Run() {
log := &JobLog{
JobName: "clean_logs",
Status: "running",
StartTime: time.Now(),
}
db.Create(log)
defer func() {
log.EndTime = time.Now()
log.Status = "success"
db.Save(log)
}()
// 执行清理
...
}