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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

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

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

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

1. 實現方式

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

字段類型        是否為必須字段   允許的值    	     允許的特殊字符
----------     ----------   --------------    --------------------------
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表達式與該字段的所有值匹配。例如,在第四個字段(月)中使用星號表示每個月;

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

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

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

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

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

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

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

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. 細節說明

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

4. 安裝方式

go get github.com/gorhill/cronexpr

5. 重要函數

5.1 cronexpr.Parse

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

5.2 cronexpr.MustParse

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

6. 代碼實現

6.1 簡單示例

package mainimport ("fmt""time""github.com/gorhill/cronexpr"
)func doTask() {fmt.Println("I am running, time is: ", time.Now())
}
func main() {// 每隔 5 秒執行1次expr, err := cronexpr.Parse("*/5 * * * * * * ") // 如果表達式解析錯誤將返回一個錯誤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 監控任務和執行任務處于不同的協程

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

總結

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

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。