Go的Cron表达式解析库:github.com/gorhill/cronexpr

核心类型和方法

// 表达式对象
expr *cronexpr.Expression
// 解析cron表达式
expr = cronexpr.Parse()
// 返回下次执行时间
expr.Next()

解析Cron表达式

func PrintCronNext() {
var (
cronLine string
expr *cronexpr.Expression
)
// 定时参数的格式 秒 分 时 日 月 周 年
cronLine = "*/5 * * * * * *"
expr, _ = cronexpr.Parse(cronLine)
// expr.Next基于某个时间给出下一次的执行时间
fmt.Println(expr.Next(time.Now()))
// expr.NextN返回多个Next时间
fmt.Println(expr.NextN(time.Now(), 5))
}

执行定时任务

// 结合time.AfterFunc实现定时任务的执行
func ExecWithCronNext() {
var (
cronLine string
expr *cronexpr.Expression
)
cronLine = "*/5 * * * * * *"
expr, _ = cronexpr.Parse(cronLine)
// AfterFunc用于在指定的Duration后执行相应的函数
// expr.Next() - time.Now() 得到相应的Duration
time.AfterFunc(expr.Next(time.Now()).Sub(time.Now()), func() {
fmt.Println("定时任务被执行了")
})
// 挂起主线程
time.Sleep(10 * time.Second)
}

实现定时任务循环调度

// 封装一个任务
type CronJob struct {
expr *cronexpr.Expression
nextTime time.Time
job func() // 传递要执行的任务
}
// 构建调度器实现循环调度
func ScheduleWithCron() {
// 调度器的本质是要循环一个调度表实现调度
var (
cronLine string
expr *cronexpr.Expression
cronJob *CronJob
scheduleTable map[string]*CronJob
)
cronLine = "*/5 * * * * * *"
// MustParse在Parse基础上当有err出现时进行Panic
expr = cronexpr.MustParse(cronLine)
// 新建任务
cronJob = &CronJob{
expr: expr,
nextTime: expr.Next(time.Now()),
job: func() {
fmt.Println("do cron job")
},
}
// map类型需要make进行内存分配
scheduleTable = make(map[string]*CronJob)
// 将任务添加到调度表
scheduleTable["job1"] = cronJob // 启动调度goroutine实现遍历调度表
go func() {
var (
jobName string
cronJob *CronJob
now time.Time
)
for {
now = time.Now()
// range是go中的遍历语法
for jobName, cronJob = range scheduleTable {
// 比较每个CronJob中的NextTime是否已经过期
if cronJob.nextTime.Before(now) || cronJob.nextTime.Equal(now) {
// 如果已经过期或者刚好相等,则启动一个goroutine来执行任务
go func() {
fmt.Printf("开始执行任务: %s \n", jobName)
cronJob.job()
}()
// 更新一下NextTime
cronJob.nextTime = cronJob.expr.Next(now)
}
}
// 控制一下遍历调度表的频率
select {
// 使用time.NewTimer创建定时器,NewTimer.C返回一个channel
// 当时间到了一个channel中会被放入一个Time类型的值从而唤醒阻塞,继续for遍历
case <- time.NewTimer(100 * time.Millisecond).C:
}
}
}()
time.Sleep(100 * time.Second)
}

GO实现Cron解析和定时任务的更多相关文章

  1. 将定时任务cron 解析成中文

    在使用定时器 quartz 时,其中的cron 表达式,老板表示作为开发的你能看懂外,其他的非开发同事可能看不懂,要用一个他们能看懂的方式表达出来. 还好我们的项目要求的表达式不是特别的麻烦,所以就写 ...

  2. 最强cron解析器

    背景 大家有没有这么一种困境 我现在需要去配置一个定时任务:"每天早上九点执行任务" 若你有一个好的定时任务平台,相信很容易就能配置完成.那若是没有定时任务平台呢?是不是就要自己写 ...

  3. PHP结合Linux的cron命令实现定时任务

    PHP死循环 来处理定时任务的效率是很低的.(众多网友评价)大家都建议使用Linux内置的定时任务crontab命令来调用php脚本来实现. PHP定时任务的两种方法:1.web方式调用php网页,但 ...

  4. docker(ubuntu)中安装cron运行crontab定时任务

    1.安装cron apt-get install cron 设置crontab定时任务 crontab -e */ * * * * /usr/bin/python /python/asch-check ...

  5. TP5 用cron实现linux定时任务

    TP5 用cron实现linux定时任务 1) tp5的控制器内容: namespace app\test\controller; use think\Controller; use think\fa ...

  6. Cron和Spring定时任务

    1.Java Spring spring定时任务cronExpression的值(配置定时时间)格式说明: 一个cronExpression表达式有至少6个(也可能是7个)由空格分隔的时间元素.从左至 ...

  7. /etc/cron.d添加定时任务脚本后不生效

    原因:定时任务脚本中的命令中包含了环境变量,crontab不能读取到环境变量. vim /etc/cron.d/mymon #mymon内容如下: * * * * * root cd $GOPATH/ ...

  8. 使用cron命令配置定时任务(cron jobs)

    原文 http://www.cnblogs.com/end/archive/2012/02/21/2361741.html 开机就启动cron进程的设置命令:chkconfig --add crond ...

  9. 使用Cron表达式创建定时任务

    CronTriggerCronTrigger功能非常强大,是基于日历的作业调度,而SimpleTrigger是精准指定间隔,所以相比SimpleTrigger,CroTrigger更加常用.CroTr ...

随机推荐

  1. 在 RPA10.X 运行异常,RPA9 却正常的问题处理

    一.现象 RPA10.X 在一些极少数 win7/win10 环境中一运行就崩溃或无运行结果. 二.原因 出现上述现象已经确定是OPenGL 驱动兼容性造成的. 三.解决方法 方法一 只要把流程的管理 ...

  2. [转]docx4j实现动态表格(模板式)

    原文地址:https://chendd.cn/information/viewInformation/other/257.a 除了前篇文章中讲到的编程式创建表格外,基于模板实现的列表表格也是非常常用或 ...

  3. 基于webpack4的react开发环境配置

    一.基础配置 1.init项目 mkdir react-webpack4-cook cd react-webpack4-cook mkdir src mkdir dist npm init -y 复制 ...

  4. 解决pytesseract.pytesseract.TesseractNotFoundError: tesseract is not installed or it's not in your path问题

    解决方案: 找到python的安装路径下的pytesseract:   例如我的是  C:\develop\Python\Lib\site-packages\pytesseract .用文本编辑器打开 ...

  5. JAVA获取树形结构

    package com.nnmzkj.common.dto; import lombok.Data; import java.io.Serializable;import java.util.Arra ...

  6. java多线程(三)线程的安全问题

    1.1. 什么是线程安全 如果有多个线程同时运行同一个实现了Runnable接口的类,程序每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的:反之,则是线程不 ...

  7. LeetCode 104. Maximum Depth of Binary Tree(二叉树深度)

    Given a binary tree, find its maximum depth. The maximum depth is the number of nodes along the long ...

  8. final,static,super,this

    ## final 关键字 **final关键字主要用在三个地方:变量.方法.类.** 1. **对于一个final变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改:如果是引用类型的变 ...

  9. JS调用onBackPressed

    需求: 安卓页面webview加载H5页面,H5页面能能返回到安卓页面 import android.os.Bundle; import android.support.v7.app.AppCompa ...

  10. [转] 2017年PHP开发者大会 鸟哥 (惠新宸@Laruence)精彩问答

    php7.1那个诡异的函数返回类型限定是如何考虑的? 鸟哥:没什么特别考虑,投票投出来的.首先说明一点,我投的是反对票.包括php的命名空间反斜杠我也是非常反对的,但可能由于我并没有对这方面太深的认识 ...