Go语言封装一个Cron定时任务管理器

 更新时间:2024年12月20日 08:57:29   作者:熬了夜的程序员  
在现代应用中,定时任务是非常常见的需求,无论是用于定时清理数据,还是定时执行系统维护任务,下面我们就来使用Go语言封装一个Cron定时任务管理器吧

介绍

在现代应用中,定时任务是非常常见的需求,无论是用于定时清理数据、定时发送邮件,还是定时执行系统维护任务。Go语言作为一门现代编程语言,提供了多种方法来实现定时任务。本文将重点介绍如何在Go中封装一个Cron定时任务管理器,帮助开发者高效管理定时任务。

目标

我们将通过使用 github.com/robfig/cron/v3 库来实现一个简洁、灵活的定时任务调度器。该库支持基于 Cron 表达式的任务调度,我们将基于该库封装出一个简单的 API,供开发者在实际项目中使用。

项目背景

Cron 表达式是一种用来表示时间计划的格式,它通常由 5 或 6 个字段组成,表示一个特定的时间点或时间间隔。Go中的 robfig/cron 库提供了非常便利的接口来处理这些表达式,并能够定期执行任务。

我们的目标是封装一个 Crontab 结构体,它将管理所有的定时任务,支持任务的添加、删除、查询以及启动和停止功能。

代码分析

下面是一个简单的 Cron 定时任务调度器的封装代码。它基于 robfig/cron 库并扩展了一个 Crontab 结构体,提供了一些常用的操作方法。

代码实现

package crontab

import (
	"github.com/pkg/errors"
	cron "github.com/robfig/cron/v3"
	"sync"
)

// Crontab crontab struct
type Crontab struct {
	inner *cron.Cron
	ids   map[string]cron.EntryID
	mutex *sync.RWMutex
}

// NewCrontab new crontab
func NewCrontab() *Crontab {
	return &Crontab{
		inner: cron.New(cron.WithSeconds()), // 支持秒级别的Cron表达式
		ids:   make(map[string]cron.EntryID),
		mutex: new(sync.RWMutex),
	}
}

// IDs 获取所有有效的Cron任务ID
func (c *Crontab) IDs() []string {
	c.mutex.RLock()
	defer c.mutex.RUnlock()

	validIDs := make([]string, 0, len(c.ids))
	invalidIDs := make([]string, 0)
	for sid, eid := range c.ids {
		if e := c.inner.Entry(eid); e.ID != eid {
			invalidIDs = append(invalidIDs, sid)
			continue
		}
		validIDs = append(validIDs, sid)
	}

	// 清理无效的任务ID
	for _, id := range invalidIDs {
		delete(c.ids, id)
	}

	return validIDs
}

// Start 启动定时任务调度器
func (c *Crontab) Start() {
	c.inner.Start()
}

// Stop 停止定时任务调度器
func (c *Crontab) Stop() {
	c.inner.Stop()
}

// DelByID 根据ID删除定时任务
func (c *Crontab) DelByID(id string) error {
	c.mutex.Lock()
	defer c.mutex.Unlock()

	eid, ok := c.ids[id]
	if !ok {
		return errors.Errorf("crontab id not exists!")
	}
	c.inner.Remove(eid)
	delete(c.ids, id)

	return nil
}

// AddByID 根据ID添加定时任务
// spec 是Cron表达式,cmd 是执行的任务
func (c *Crontab) AddByID(id, spec string, cmd cron.Job) error {
	c.mutex.Lock()
	defer c.mutex.Unlock()

	if _, ok := c.ids[id]; ok {
		return errors.Errorf("crontab id exists!")
	}
	eid, err := c.inner.AddJob(spec, cmd)
	if err != nil {
		return err
	}
	c.ids[id] = eid
	return nil
}

// AddByFunc 根据ID添加函数作为定时任务
func (c *Crontab) AddByFunc(id, spec string, f func()) error {
	c.mutex.Lock()
	defer c.mutex.Unlock()

	if _, ok := c.ids[id]; ok {
		return errors.Errorf("crontab id exists!")
	}
	eid, err := c.inner.AddFunc(spec, f)
	if err != nil {
		return err
	}
	c.ids[id] = eid
	return nil
}

// IsExists 判断某个任务ID是否已存在
func (c *Crontab) IsExists(jid string) bool {
	c.mutex.RLock()
	defer c.mutex.RUnlock()

	_, exist := c.ids[jid]
	return exist
}

主要功能

NewCrontab(): 初始化一个新的 Crontab 实例,内部使用 cron.New() 来创建一个 Cron 调度器,支持秒级别的 Cron 表达式。

IDs(): 获取当前所有有效的定时任务ID。会清理掉无效的任务ID。

Start(): 启动 Cron 调度器,开始执行所有的定时任务。

Stop(): 停止 Cron 调度器,暂停定时任务的执行。

DelByID(id): 根据任务ID删除定时任务。

AddByID(id, spec, cmd): 根据 Cron 表达式添加一个新的定时任务。任务ID必须唯一。

AddByFunc(id, spec, f): 将一个函数作为定时任务来添加,使用 Cron 表达式来指定执行频率。

IsExists(jid): 判断某个定时任务ID是否存在。

Cron表达式解析

Cron 表达式是定时任务调度中常见的表示方式,它由五个或六个字段组成,每个字段代表一个时间单位。标准的 Cron 表达式格式如下:

* * * * * *
│ │ │ │ │ │
│ │ │ │ │ └─ 星期几 (0 - 7) (0或7代表星期天)
│ │ │ │ └──── 月份 (1 - 12)
│ │ │ └────── 日 (1 - 31)
│ │ └──────── 小时 (0 - 23)
│ └────────── 分钟 (0 - 59)
└──────────── 秒 (0 - 59)

例子

  • * * * * * *:每秒执行一次任务
  • 0 * * * * *:每分钟的第0秒执行一次任务
  • 0 0 * * * *:每天午夜执行一次任务
  • 0 0 1 * * *:每月的第一天执行一次任务

使用示例

以下是如何使用封装好的 Crontab 类型来管理定时任务的示例:

package main

import (
	"fmt"
	"github.com/robfig/cron/v3"
	"time"
	"your_project/crontab"
)

func main() {
	// 创建一个新的 Crontab 实例
	c := crontab.NewCrontab()

	// 定义一个定时任务
	task := func() {
		fmt.Println("Task executed at", time.Now())
	}

	// 添加定时任务
	err := c.AddByFunc("task1", "*/5 * * * * *", task) // 每5秒执行一次
	if err != nil {
		fmt.Println("Error adding task:", err)
		return
	}

	// 启动任务调度器
	c.Start()

	// 等待一段时间后停止
	time.Sleep(20 * time.Second)
	c.Stop()

	// 删除任务
	err = c.DelByID("task1")
	if err != nil {
		fmt.Println("Error deleting task:", err)
	}
}

总结

通过使用 robfig/cron 库并封装成一个简单易用的 Crontab 类型,我们可以非常方便地在 Go 项目中管理定时任务。Cron 表达式为我们提供了灵活的时间配置,帮助开发者应对复杂的定时任务调度需求。

在实际应用中,我们可以根据需要扩展 Crontab 类型,支持更多功能,如任务状态监控、任务重试等,进一步提高定时任务管理的效率。

到此这篇关于Go语言封装一个Cron定时任务管理器的文章就介绍到这了,更多相关Go封装Cron定时任务内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 基于go实例网络存储协议详解

    基于go实例网络存储协议详解

    这篇文章主要为大家介绍了基于go实例网络存储协议详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-03-03
  • golang JSON序列化和反序列化示例详解

    golang JSON序列化和反序列化示例详解

    通过使用Go语言的encoding/json包,你可以轻松地处理JSON数据,无论是在客户端应用、服务器端应用还是其他类型的Go程序中,这篇文章主要介绍了golang JSON序列化和反序列化,需要的朋友可以参考下
    2024-04-04
  • Go语言中结构体方法副本传参与指针传参的区别介绍

    Go语言中结构体方法副本传参与指针传参的区别介绍

    这篇文章主要给大家介绍了关于Go语言中结构体方法副本传参与指针传参的区别的相关资料,文中先对GO语言结构体方法跟结构体指针方法的区别进行了一些简单的介绍,来帮助大家理解学习,需要的朋友可以参考下。
    2017-12-12
  • GoLand一键上传项目到远程服务器的方法步骤

    GoLand一键上传项目到远程服务器的方法步骤

    我们开发项目常常将项目上传到linux远程服务器上来运行,本文主要介绍了GoLand一键上传项目到远程服务器的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • Golang CSP并发机制及使用模型

    Golang CSP并发机制及使用模型

    这篇文章主要为大家介绍了Golang CSP并发机制及使用模型,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-05-05
  • Go设计模式之观察者模式讲解和代码示例

    Go设计模式之观察者模式讲解和代码示例

    观察者是一种行为设计模式, 允许一个对象将其状态的改变通知其他对象,观察者模式提供了一种作用于任何实现了订阅者接口的对象的机制, 可对其事件进行订阅和取消订阅,本文就通过代码示例给大家详细介绍一下Go的观察者模式,需要的朋友可以参考下
    2023-07-07
  • 源码剖析Golang中singleflight的应用

    源码剖析Golang中singleflight的应用

    这篇文章主要为大家详细介绍了如何利用singleflight来避免缓存击穿,并剖析singleflight包的源码实现和工作原理,感兴趣的可以了解下
    2024-03-03
  • golang qq邮件发送验证码功能

    golang qq邮件发送验证码功能

    验证码在多个场景下发挥着重要作用,如注册/登录、短信接口保护、提交/投票、密码找回和支付验证等,以保障账号安全和防止恶意操作,此外,文章还介绍了使用golang通过qq邮件发送验证码的实现过程,包括获取授权码、下载依赖包和编写代码,感兴趣的朋友跟随小编一起看看吧
    2024-09-09
  • Go语言Handler详细说明

    Go语言Handler详细说明

    这篇文章主要介绍了Go语言Handler详细说明,Handler用于处理请求并给予响应。更严格地说,用来读取请求体、并将请求对应的响应字段(respones header)写入ResponseWriter中,需要的朋友可以参考下
    2022-04-04
  • Go与Rust高性能解析JSON实现方法示例

    Go与Rust高性能解析JSON实现方法示例

    这篇文章主要为大家介绍了Go与Rust高性能的解析JSON实现方法示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12

最新评论