feat: 添加数据库集成、定时任务调度器和事件Hook体系
- 新增数据库配置项(DB_TYPE, DB_HOST, DB_PORT等),支持MySQL和PostgreSQL - 集成GORM实现数据库连接和自动迁移功能 - 添加定时任务调度器(cmd/scheduler),基于robfig/cron实现秒级调度 - 实现事件Hook体系,支持同步/异步处理和优先级排序 - 更新构建脚本,编译server、cli、scheduler三个二进制文件 - 配置systemd服务管理定时任务调度器 - 重构项目结构,新增crontab和hooks目录模块 - 更新README文档,完善各组件使用说明和部署配置
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
package crontab
|
||||
|
||||
import (
|
||||
"apiServer_service/utils/logger"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/robfig/cron/v3"
|
||||
)
|
||||
|
||||
// Task 定时任务接口
|
||||
type Task interface {
|
||||
Name() string
|
||||
Spec() string
|
||||
Run()
|
||||
}
|
||||
|
||||
type Scheduler struct {
|
||||
cron *cron.Cron
|
||||
tasks []Task
|
||||
mu sync.RWMutex
|
||||
}
|
||||
|
||||
var (
|
||||
defaultScheduler *Scheduler
|
||||
once sync.Once
|
||||
)
|
||||
|
||||
func DefaultScheduler() *Scheduler {
|
||||
once.Do(func() {
|
||||
defaultScheduler = NewScheduler()
|
||||
})
|
||||
return defaultScheduler
|
||||
}
|
||||
|
||||
func NewScheduler() *Scheduler {
|
||||
return &Scheduler{
|
||||
cron: cron.New(cron.WithSeconds()),
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Scheduler) Register(task Task) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
entryID, err := s.cron.AddFunc(task.Spec(), func() {
|
||||
logger.CronInfo("Cron", fmt.Sprintf("执行任务: %s", task.Name()))
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
logger.CronError("Cron", fmt.Sprintf("任务 %s panic: %v", task.Name(), r))
|
||||
}
|
||||
}()
|
||||
task.Run()
|
||||
})
|
||||
if err != nil {
|
||||
logger.CronError("Cron", fmt.Sprintf("注册任务失败: %s, %v", task.Name(), err))
|
||||
return
|
||||
}
|
||||
s.tasks = append(s.tasks, task)
|
||||
logger.CronInfo("Cron", fmt.Sprintf("注册任务: %s [%s] (id=%d)", task.Name(), task.Spec(), entryID))
|
||||
}
|
||||
|
||||
func (s *Scheduler) Start() {
|
||||
logger.CronInfo("Cron", fmt.Sprintf("调度器启动,已注册 %d 个任务", len(s.tasks)))
|
||||
s.cron.Start()
|
||||
}
|
||||
|
||||
func (s *Scheduler) Stop() {
|
||||
logger.CronInfo("Cron", "调度器停止")
|
||||
ctx := s.cron.Stop()
|
||||
<-ctx.Done()
|
||||
}
|
||||
|
||||
func (s *Scheduler) RunOnce() {
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
for _, task := range s.tasks {
|
||||
logger.CronInfo("Cron", fmt.Sprintf("立即执行: %s", task.Name()))
|
||||
task.Run()
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Scheduler) RunTaskByName(name string) bool {
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
for _, task := range s.tasks {
|
||||
if task.Name() == name {
|
||||
task.Run()
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *Scheduler) GetTasks() []Task {
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
return s.tasks
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package tasks
|
||||
|
||||
import (
|
||||
"apiServer_service/utils/logger"
|
||||
"fmt"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
// HealthCheckTask 健康检查示例任务
|
||||
type HealthCheckTask struct{}
|
||||
|
||||
func (t *HealthCheckTask) Name() string {
|
||||
return "健康检查"
|
||||
}
|
||||
|
||||
func (t *HealthCheckTask) Spec() string {
|
||||
return "0 */5 * * * *"
|
||||
}
|
||||
|
||||
func (t *HealthCheckTask) Run() {
|
||||
var m runtime.MemStats
|
||||
runtime.ReadMemStats(&m)
|
||||
logger.CronInfo("HealthCheck", fmt.Sprintf(
|
||||
"goroutines=%d, heap=%dMB, sys=%dMB",
|
||||
runtime.NumGoroutine(), m.HeapAlloc/1024/1024, m.Sys/1024/1024,
|
||||
))
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package tasks
|
||||
|
||||
import (
|
||||
"apiServer_service/crontab"
|
||||
)
|
||||
|
||||
// RegisterTasks 注册所有定时任务,新增任务在此添加
|
||||
func RegisterTasks(scheduler *crontab.Scheduler) {
|
||||
scheduler.Register(&HealthCheckTask{})
|
||||
|
||||
// 新增任务示例:
|
||||
// scheduler.Register(NewXxxTask())
|
||||
}
|
||||
Reference in New Issue
Block a user