日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

Go 学习笔记(77)— Go 第三方库之 cronexpr(解析 crontab 表达式,定时任务)

發(fā)布時間:2023/11/28 生活经验 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Go 学习笔记(77)— Go 第三方库之 cronexpr(解析 crontab 表达式,定时任务) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

cronexpr 支持的比 Linux 自身的 crontab 更詳細(xì),可以精確到秒級別。
?

1. 實(shí)現(xiàn)方式

cronexpr 表達(dá)式從前到后的順序如下所示:

字段類型        是否為必須字段   允許的值    	     允許的特殊字符
----------     ----------   --------------    --------------------------
Seconds        No           0-59              * / , -
Minutes        Yes          0-59              * / , -
Hours          Yes          0-23              * / , -
Day of month   Yes          1-31              * / , - L W
Month          Yes          1-12 or JAN-DEC   * / , -
Day of week    Yes          0-6 or SUN-SAT    * / , - L #
Year           No           1970–2099         * / , -

我們定義第 0 個字段為 Seconds,第 1 個字段為 Minutes,各個字段的含義如下:

  • * 星號表示 cron表達(dá)式與該字段的所有值匹配。例如,在第四個字段(月)中使用星號表示每個月;

  • / 斜線描述在該時間段的間隔。例如,分鐘字段中的 3-59/15表示每小時的第三分鐘,此后每15分鐘。*/...的形式相當(dāng)于 first-last/... 的形式,即在該字段的最大可能范圍內(nèi)的增量;

  • , 逗號用于分隔列表中的項(xiàng)目。例如,在第 5 個字段(星期)中使用 MON,WED,FRI表示星期一、星期三和星期五;

  • - 連字符定義范圍。例如,2000-2010表示公元 2000 年至 2010 年之間的每一年,包括在內(nèi),為閉區(qū)間;

  • L 代表 “最后”。當(dāng)在周天字段中使用時,它允許你指定諸如 “最后一個星期五”(5L)這樣的結(jié)構(gòu)。在月日字段中,它指定了該月的最后一天;

  • W 月日字段允許使用 W 字符。這個字符用于指定離給定日期最近的工作日(周一至周五)。舉個例子,如果你指定 15W作為月日字段的值,其含義是:“離本月 15 日最近的工作日”。所以,如果 15 號是星期六,觸發(fā)器在 14 號星期五啟動。如果 15 號是星期天,觸發(fā)器在 16 號星期一啟動。如果 15 號是星期二,那么它就在 15 號星期二觸發(fā)。但是,如果你指定 1W 作為月日的值,并且 1 號是星期六,那么觸發(fā)器在 3 號星期一發(fā)射,因?yàn)樗粫?"跳過 "一個月的天數(shù)邊界。

    只有當(dāng)月日是一個單一的日子,而不是一個范圍或日期列表時,才能指定 W 字符。W 字符也可以與 L結(jié)合使用,如 LW表示 “本月的最后一個工作日”。

  • # 允許在星期字段中使用 #,后面必須有一個 1 到 5 之間的數(shù)字。它允許你指定一些結(jié)構(gòu),如某個月的 “第二個星期五”。

2. 示例說明

Entry       Description                                                             Equivalent to
@annually   Run once a year at midnight in the morning of January 1                 0 0 0 1 1 * *
@yearly     Run once a year at midnight in the morning of January 1                 0 0 0 1 1 * *
@monthly    Run once a month at midnight in the morning of the first of the month   0 0 0 1 * * *
@weekly     Run once a week at midnight in the morning of Sunday                    0 0 0 * * 0 *
@daily      Run once a day at midnight                                              0 0 0 * * * *
@hourly     Run once an hour at the beginning of the hour                           0 0 * * * * *
@reboot     Not supported

3. 細(xì)節(jié)說明

  • 如果只有六個字段,則會預(yù)加一個 0 秒字段,即 * * * * * 2013在內(nèi)部成為 0 * * * * 2013
  • 如果只有五個字段,則預(yù)設(shè) 0 秒字段,并附加一個通配符年份字段,即 * * * * Mon內(nèi)部成為 0 * * * Mon *
  • 星期字段的域是 [0-7],而不是 [0-6],7 是星期天(像0)。這是為了符合http://linux.die.net/man/5/crontab#;
  • 如果提供了一個錯誤的cron表達(dá)式,代碼的行為是不確定的;

4. 安裝方式

go get github.com/gorhill/cronexpr

5. 重要函數(shù)

5.1 cronexpr.Parse

expr, err := cronexpr.Parse("*/5 * * * * * * ") // 如果表達(dá)式解析錯誤將返回一個錯誤

5.2 cronexpr.MustParse

expr = cronexpr.MustParse("*/5 * * * * * * ")   // 如果表達(dá)式解析錯誤將直接拋出 panic

6. 代碼實(shí)現(xiàn)

6.1 簡單示例

package mainimport ("fmt""time""github.com/gorhill/cronexpr"
)func doTask() {fmt.Println("I am running, time is: ", time.Now())
}
func main() {// 每隔 5 秒執(zhí)行1次expr, err := cronexpr.Parse("*/5 * * * * * * ") // 如果表達(dá)式解析錯誤將返回一個錯誤if err != nil {fmt.Println(err)return}nextTime := expr.Next(time.Now())fmt.Println(nextTime)time.AfterFunc(time.Until(nextTime), doTask)time.Sleep(10 * time.Second)}

6.2 監(jiān)控任務(wù)和執(zhí)行任務(wù)處于不同的協(xié)程

package mainimport ("fmt""time""github.com/gorhill/cronexpr"
)// 代表一個任務(wù)
type CronJob struct {expr     *cronexpr.ExpressionnextTime time.Time // expr.Next(now)
}func main() {// 定時任務(wù)字典, key: 任務(wù)的名字, value 任務(wù)對象scheduleTable := make(map[string]*CronJob)now := time.Now()// 定義定時任務(wù)以每 5s 執(zhí)行一次// MustParse 如果遇到解析 contab 錯誤時會直接拋出 panic ,不會像 Parse 一樣返回一個錯誤expr := cronexpr.MustParse("*/5 * * * * * *")cronJob := &CronJob{expr:     expr,nextTime: expr.Next(now),}// 任務(wù)注冊到調(diào)度表scheduleTable["job1"] = cronJob// 定義定時任務(wù)以每 3s 執(zhí)行一次expr = cronexpr.MustParse("*/3 * * * * * *")cronJob = &CronJob{expr:     expr,nextTime: expr.Next(now),}// 任務(wù)注冊到調(diào)度表scheduleTable["job2"] = cronJob// 定時檢查一下任務(wù)調(diào)度表for {now := time.Now()for jobName, cronJob := range scheduleTable {// 判斷是否到期,當(dāng)前時間等于定時任務(wù)的下次執(zhí)行時間,或者當(dāng)前時間大于任務(wù)的定時時間if now.Equal(cronJob.nextTime) || now.After(cronJob.nextTime) {// 啟動一個協(xié)程, 執(zhí)行這個任務(wù)go func(jobName string) {fmt.Println("執(zhí)行:", jobName)}(jobName)// 計(jì)算下一次調(diào)度時間cronJob.nextTime = cronJob.expr.Next(now)fmt.Println(jobName, "下次執(zhí)行時間:", cronJob.nextTime)}}// 等待 1s,減少 CPU 消耗t := <-time.NewTimer(1 * time.Second).Cfmt.Println(t)}}

總結(jié)

以上是生活随笔為你收集整理的Go 学习笔记(77)— Go 第三方库之 cronexpr(解析 crontab 表达式,定时任务)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。