From ce87579e5f922bb31cd2c44a84ced93b7c63196f Mon Sep 17 00:00:00 2001 From: songzhibin97 <718428482@qq.com> Date: Sat, 17 Apr 2021 14:50:44 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=AE=9A=E6=97=B6=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E5=B0=81=E8=A3=85=E4=BB=A5=E5=8F=8A=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E6=B8=85=E7=90=86=E6=95=B0=E6=8D=AE=E5=BA=93?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增 - server/config/timer.go - server/initialize/timer.go - server/utils/db_automation.go - server/utils/timer/timed_task.go 修改 - server/config.yaml - server/config/config/go - server/global/global.go - server/main.go --- server/config.yaml | 15 ++++- server/config/config.go | 1 + server/config/timer.go | 13 ++++ server/global/global.go | 6 +- server/go.mod | 1 + server/initialize/timer.go | 24 +++++++ server/main.go | 1 + server/utils/db_automation.go | 29 ++++++++ server/utils/timer/timed_task.go | 109 +++++++++++++++++++++++++++++++ 9 files changed, 197 insertions(+), 2 deletions(-) create mode 100644 server/config/timer.go create mode 100644 server/initialize/timer.go create mode 100644 server/utils/db_automation.go create mode 100644 server/utils/timer/timed_task.go diff --git a/server/config.yaml b/server/config.yaml index d57d6963..90ad95d9 100644 --- a/server/config.yaml +++ b/server/config.yaml @@ -114,4 +114,17 @@ tencent-cos: # excel configuration excel: - dir: './resource/excel/' \ No newline at end of file + dir: './resource/excel/' + + +# timer task db clear table +Timer: + spec: "@daily" # 定时任务详细配置参考 https://pkg.go.dev/github.com/robfig/cron?utm_source=godoc + detail: [ + # tableName: 需要清理的表名 + # compareField: 需要比较时间的字段 + # interval: 时间间隔, 具体配置详看 time.ParseDuration() 中字符串表示 且不能为负数 + # 2160h = 24 * 30 * 3 -> 三个月 + { tableName: "log" , compareField: "created_at", interval: "2160h" }, + { tableName: "log2" , compareField: "created_at", interval: "2160h" } + ] diff --git a/server/config/config.go b/server/config/config.go index e2e557de..83d256f4 100644 --- a/server/config/config.go +++ b/server/config/config.go @@ -18,4 +18,5 @@ type Server struct { AliyunOSS AliyunOSS `mapstructure:"aliyun-oss" json:"aliyunOSS" yaml:"aliyun-oss"` TencentCOS TencentCOS `mapstructure:"tencent-cos" json:"tencentCOS" yaml:"tencent-cos"` Excel Excel `mapstructure:"excel" json:"excel" yaml:"excel"` + Timer Timer `mapstructure:"timer" json:"timer" yaml:"timer"` } diff --git a/server/config/timer.go b/server/config/timer.go new file mode 100644 index 00000000..f83d6bf0 --- /dev/null +++ b/server/config/timer.go @@ -0,0 +1,13 @@ +package config + +type Timer struct { + Start bool `mapstructure:"start" json:"start" yaml:"start"` + Spec string `mapstructure:"spec" json:"spec" yaml:"spec"` + Detail []Detail `mapstructure:"detail" json:"detail" yaml:"detail"` +} + +type Detail struct { + TableName string `mapstructure:"tableName" json:"tableName" yaml:"tableName"` + CompareField string `mapstructure:"compareField" json:"compareField" yaml:"compareField"` + Interval string `mapstructure:"interval" json:"interval" yaml:"interval"` +} diff --git a/server/global/global.go b/server/global/global.go index 98312d82..43577a4c 100644 --- a/server/global/global.go +++ b/server/global/global.go @@ -1,9 +1,12 @@ package global import ( + "gin-vue-admin/utils/timer" + "go.uber.org/zap" "gin-vue-admin/config" + "github.com/go-redis/redis" "github.com/spf13/viper" "gorm.io/gorm" @@ -15,5 +18,6 @@ var ( GVA_CONFIG config.Server GVA_VP *viper.Viper //GVA_LOG *oplogging.Logger - GVA_LOG *zap.Logger + GVA_LOG *zap.Logger + GVA_Timer timer.Timer = timer.NewTimerTask() ) diff --git a/server/go.mod b/server/go.mod index f42f521e..e9900c03 100644 --- a/server/go.mod +++ b/server/go.mod @@ -36,6 +36,7 @@ require ( github.com/pelletier/go-toml v1.6.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/qiniu/api.v7/v7 v7.4.1 + github.com/robfig/cron/v3 v3.0.1 github.com/satori/go.uuid v1.2.0 github.com/shirou/gopsutil v3.21.1+incompatible github.com/spf13/afero v1.2.2 // indirect diff --git a/server/initialize/timer.go b/server/initialize/timer.go new file mode 100644 index 00000000..6fa27913 --- /dev/null +++ b/server/initialize/timer.go @@ -0,0 +1,24 @@ +package initialize + +import ( + "fmt" + "gin-vue-admin/config" + "gin-vue-admin/global" + "gin-vue-admin/utils" +) + +func Timer() { + if global.GVA_CONFIG.Timer.Start { + for _, detail := range global.GVA_CONFIG.Timer.Detail { + fmt.Println(detail) + go func(detail config.Detail) { + global.GVA_Timer.AddTaskByFunc("ClearDB", global.GVA_CONFIG.Timer.Spec, func() { + err := utils.ClearTable(global.GVA_DB, detail.TableName, detail.CompareField, detail.Interval) + if err != nil { + fmt.Println("timer error:", err) + } + }) + }(detail) + } + } +} diff --git a/server/main.go b/server/main.go index c772d327..ee9080f1 100644 --- a/server/main.go +++ b/server/main.go @@ -17,6 +17,7 @@ func main() { global.GVA_VP = core.Viper() // 初始化Viper global.GVA_LOG = core.Zap() // 初始化zap日志库 global.GVA_DB = initialize.Gorm() // gorm连接数据库 + initialize.Timer() if global.GVA_DB != nil { initialize.MysqlTables(global.GVA_DB) // 初始化表 // 程序结束前关闭数据库链接 diff --git a/server/utils/db_automation.go b/server/utils/db_automation.go new file mode 100644 index 00000000..c3743b92 --- /dev/null +++ b/server/utils/db_automation.go @@ -0,0 +1,29 @@ +package utils + +import ( + "errors" + "fmt" + "time" + + "gorm.io/gorm" +) + +//@author: [songzhibin97](https://github.com/songzhibin97) +//@function: ClearTable +//@description: 清理数据库表数据 +//@param: target db(数据库对象) *gorm.DB,tableName(表名) string,compareField(比较字段) string , interval string 间隔 +//@return: err + +func ClearTable(db *gorm.DB, tableName string, compareField string, interval string) error { + if db == nil { + return errors.New("db Cannot be empty") + } + duration, err := time.ParseDuration(interval) + if err != nil { + return err + } + if duration < 0 { + return errors.New("parse duration < 0") + } + return db.Debug().Exec(fmt.Sprintf("DELETE FROM %s WHERE %s < ?", tableName, compareField), time.Now().Add(-duration)).Error +} diff --git a/server/utils/timer/timed_task.go b/server/utils/timer/timed_task.go new file mode 100644 index 00000000..881fddeb --- /dev/null +++ b/server/utils/timer/timed_task.go @@ -0,0 +1,109 @@ +package timer + +import ( + "sync" + + "github.com/robfig/cron/v3" +) + +type Timer interface { + AddTaskByFunc(taskName string, spec string, task func()) (cron.EntryID, error) + AddTaskByJob(taskName string, spec string, job interface{ Run() }) (cron.EntryID, error) + FindCron(taskName string) (*cron.Cron, bool) + StartTask(taskName string) + StopTask(taskName string) + Remove(taskName string, id int) + Clear(taskName string) + Close() +} + +// timer 定时任务管理 +type timer struct { + taskList map[string]*cron.Cron + sync.Mutex +} + +// AddTaskByFunc 通过函数的方法添加任务 +func (t *timer) AddTaskByFunc(taskName string, spec string, task func()) (cron.EntryID, error) { + t.Lock() + defer t.Unlock() + if _, ok := t.taskList[taskName]; !ok { + t.taskList[taskName] = cron.New() + } + id, err := t.taskList[taskName].AddFunc(spec, task) + t.taskList[taskName].Start() + return id, err +} + +// AddTaskByJob 通过接口的方法添加任务 +func (t *timer) AddTaskByJob(taskName string, spec string, job interface{ Run() }) (cron.EntryID, error) { + t.Lock() + defer t.Unlock() + if _, ok := t.taskList[taskName]; !ok { + t.taskList[taskName] = cron.New() + } + id, err := t.taskList[taskName].AddJob(spec, job) + t.taskList[taskName].Start() + return id, err +} + +// FindCron 获取对应taskName的cron 可能会为空 +func (t *timer) FindCron(taskName string) (*cron.Cron, bool) { + t.Lock() + defer t.Unlock() + v, ok := t.taskList[taskName] + return v, ok +} + +// StartTask 开始任务 +func (t *timer) StartTask(taskName string) { + t.Lock() + defer t.Unlock() + if v, ok := t.taskList[taskName]; ok { + v.Start() + } + return +} + +// StopTask 停止任务 +func (t *timer) StopTask(taskName string) { + t.Lock() + defer t.Unlock() + if v, ok := t.taskList[taskName]; ok { + v.Stop() + } + return +} + +// Remove 从taskName 删除指定任务 +func (t *timer) Remove(taskName string, id int) { + t.Lock() + defer t.Unlock() + if v, ok := t.taskList[taskName]; ok { + v.Remove(cron.EntryID(id)) + } + return +} + +// Clear 清除任务 +func (t *timer) Clear(taskName string) { + t.Lock() + defer t.Unlock() + if v, ok := t.taskList[taskName]; ok { + v.Stop() + delete(t.taskList, taskName) + } +} + +// Close 释放资源 +func (t *timer) Close() { + t.Lock() + defer t.Unlock() + for _, v := range t.taskList { + v.Stop() + } +} + +func NewTimerTask() Timer { + return &timer{taskList: make(map[string]*cron.Cron)} +} -- GitLab