每天如何在特定时间运行一个任务?

3

我希望每天晚上9点打印出do my job。在Go语言中,我该如何做到这一点?

这是我目前已经得到的:

timer := time.NewTimer(3 * time.Second)
for {
    now := time.Now()
    next := now.Add(time.Hour * 24)
    todayNine := time.Date(next.Year(), next.Month(), next.Day(), 9, 0, 0, 0, next.Location()).AddDate(0, 0, -1)
    todayFifteen := time.Date(next.Year(), next.Month(), next.Day(), 15, 0, 0, 0, next.Location()).AddDate(0, 0, -1)
    todayEnd := time.Date(next.Year(), next.Month(), next.Day(), 0, 0, 0, 0, next.Location()).AddDate(0, 0,  -1)
    if now.Before(todayNine) {
        timer.Reset(todayNine.Sub(now))
    } else if now.Before(todayFifteen) {
        timer.Reset(todayFifteen.Sub(now))
    } else if now.Before(todayEnd) {
        timer.Reset(todayEnd.Sub(now))
    }
    <- timer.C
    fmt.Println("do my job")
}

1
你可以使用计时器和检查时间的小时部分Now()。但是如果有多个实例运行,这可能会变得棘手...每个实例都会执行一次任务。 - undefined
2
我建议使用go二进制之外的不同系统来启动作业。可以使用cron作业或k8 cron。如果您想纯粹使用go,应该使用"ticker"。 - undefined
2
你的操作系统可能有一种方法可以定期安排程序在特定时间运行,就像你想要的那样。你使用的是什么操作系统? - undefined
抱歉我没有尽快回复,这是我的解决方案,请告诉我你的想法,谢谢! - undefined
2个回答

3
我会探索操作系统级别或基础设施级别的系统,在这些时间点触发执行(如*nix中的Cron作业,k8s中的Cron等)。
然而,如果你想纯粹使用go来完成,可以尝试同时使用ticker和Clock。
package main

import (
    "context"
    "fmt"
    "os"
    "time"
    "os/signal"
)

func main() {
    ticker := time.NewTicker(time.Minute)
    done := make(chan bool)
    ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
    defer stop()
    go func() {
        for {
            select {
            case <-done:
                return
            case <-ticker.C:
                h, m, _ := time.Now().Clock()
                if m == 0 && (  h == 9 || h == 15 ) {
                    fmt.Printf("Doing the job")
                }
            }
        }
    }()

    <-ctx.Done()
    stop()
    done <- true
}

链接到演示版


如果您停止并重新运行服务器,那么这将成为重新启动的凭证吗?因此,在这种情况下,使用凭证可能不太准确,我之前是用它来实现提醒功能。我更喜欢使用crontab,并创建一个类似的作业终点,这样可以运行一个脚本来访问该终点,并为您的虚拟机设置白名单IP。 - undefined
@Pocket,正如我在问题的回答和评论中提到的那样,在这种情况下,一个基础设施级别的触发器在go二进制文件之外是理想的选择。但是,如果出于某种原因他们希望纯粹使用go来完成,这是一个可行的解决方案。 - undefined
抱歉我没有尽快回复,这是我的解决方案,请告诉我你的想法,谢谢! - undefined

2

我会使用 cron 包。 https://pkg.go.dev/github.com/robfig/cron

以下是文档中的示例:

c := cron.New()
c.AddFunc("0 30 * * * *", func() { fmt.Println("Every hour on the half hour") })
c.AddFunc("@hourly",      func() { fmt.Println("Every hour") })
c.AddFunc("@every 1h30m", func() { fmt.Println("Every hour thirty") })
c.Start()
..
// Funcs are invoked in their own goroutine, asynchronously.
...
// Funcs may also be added to a running Cron
c.AddFunc("@daily", func() { fmt.Println("Every day") })
..
// Inspect the cron job entries' next and previous run times.
inspect(c.Entries())
..
c.Stop()  // Stop the scheduler (does not stop any jobs already running).

抱歉我没有尽快回复,这是我的解决方案,请告诉我你的想法,谢谢! - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接